Introduction à R

Statistique descriptive univariée et bivariée

Master G2M, 2-4 septembre 2025
Authors
Affiliations

Elina Marveaux

Géographie-Cités, CNRS

Louis Laurian

UAR RIATE, CNRS

Objectifs de ce cours
  1. Acquérir les bases du logiciel/langage R et de son environnement RStudio
  2. Réviser les bases de la statistique descriptive univariée et bivariée en géographie
  3. Comprendre les atouts de R pour la gestion, l’analyse et la représentation de données

Diaporama : Contextualisation et présentation de R et Rstudio

Bonus : Base du langage, packages, Rstudio et documentation

1 Quelques fondamentaux

1.1 L’interface Rstudio

L’interface de RStudio se présente sous la forme d’une unique fenêtre découpée en quatre zones que l’on peut redimensionner, masquer ou maximiser selon ses préférences :

  • L’éditeur de code Cette zone permet l’édition de fichiers source R (avec coloration syntaxique et auto complétion).

  • La console La console avec la session R en cours d’exécution. La console affiche à la fois le code exécuté, ses résultats associés, ainsi que les avertissements (Warning) et messages d’erreur éventuels (Error).

  • L’espace de travail Cette zone permet de lister, typer et visualiser les objets créés par l’exécution du code R.

  • Une quatrième zone permettant de basculer entre : Un explorateur de fichiers, une fenêtre graphique, une fenêtre de gestion des packages et de la documentation associée aux fonctions et packages.

RStudio propose de nombreuses fonctionnalités intéressantes, par exemple :

La création de projet

RStudio dispose d’une fonctionnalité très pratique pour organiser son travail en différents projets. L’idée principale est de réunir tous les fichiers et documents relatifs à un même projet (que ce soit les données, les scripts, les rapports automatisés…) dans un répertoire dédié. L’onglet “Projects” est situé en haut à droite de l’interface.

Les boutons raccourcis Plusieurs actions comme la création et le chargement de programme, l’import de données, l’installation et le chargement de packages, l’accès à la documentation, la visualisation des objets, l’export de figures… sont exécutables en un simple clic.

L’auto-complétion

RStudio présente aussi la capacité de compléter automatiquement les termes en cours d’écriture. L’auto-complétion fonctionne avec la touche Tab du clavier. Cela aide l’utilisateur dans la saisi des noms d’objet, de fonction, de variable, et même des arguments de fonction.

Raccourcis clavier

RStudio propose de nombreux raccourcis clavier intéressants, exemple :

  • Alt + - renvoie l’opérateur d’assignation accompagné d’un espace avant et un espace après (<-)

  • Ctrl + Enter exécute le code écrit dans la fenêtre d’édition (script)

  • Ctrl + 1 et Ctrl + 2 permettent de passer de la console à l’éditeur de code et vice versa

  • shift + Alt + k pour accéder à l’ensemble des raccourcis.

1.2 Paramètres généraux

Pour éviter des problèmes d’encodage des scripts ou le chargement incessant de données à chaque nouvelle instance de Rstudio, il est nécessaire de modifier certains paramètres globaux. Pour cela, cliquez sur “tools” puis sur “Global Options” pour ouvrir la fenêtre des paramètre généraux de Rstudio.

Dans un premier temps, décochez les options de restauration et de sauvegarde de données à l’ouverture et à la fermeture de session :

Puis, dans l’onglet “code” et le sous-onglet “saving”, paramétrez l’encodage en UTF-8 pour que les scripts crées s’affichent correctement en cas d’ouverture dans un autres systèmes d’exploitation :

1.3 Les projets

Cette fonctionnalité permet d’organiser son travail en différents projets. L’idée principale est de réunir tous les fichiers relatifs à un même projet (quelque soit leur format) dans un répertoire dédié. Le menuProjectest accessible via une icône dédiée située tout en haut à droite :

Dans le menu “Project”, sélectionnez l’option “New project” :

Dans un nouveau répertoire, créez un projet vide. Indiquez le nom de votre projet, qui sera également le nom du répertoire créé pour stocker les données du projet. Puis, indiquez le répertoire parent, dans lequel votre projet sera créé :

1.4 Les objets

Tout ce qui est créé et manipulé sous R est un objet. Ces objets permettent de stocker et de structurer les données. Les objets peuvent stocker différents types de données. Voici les principaux :

  • La chaîne de caractères (string) : Il s’agit d’une suite ordonnée de caractères, mise entre guillemets. Ex : “Ma chaîne de caractères” ou “234

  • Nombre entier (integer) : Il s’agit d’un nombre sans décimale (sans virgule). Ex : 347

  • Nombre réel (numeric) : Il s’agit d’un nombre décimal. Ex : 86.6

  • Valeur logique ou booléenne (logical) : Une variable booléenne est une variable qui ne prend que deux valeurs : TRUE (vrai) et FALSE (faux) ou 0 et 1

1.4.1 Créer un objet

Un objet peut être créé avec l’opérateur « assigner » (<-), une flèche composée du signe inférieur (<) accolée à un tiret (-). Si l’objet existe déjà, sa valeur précédente est remplacée par la nouvelle. La valeur renvoyée peut être le résultat d’une opération et/ou d’une fonction :

n <- "chaîne de caractères"

n
[1] "chaîne de caractères"
n <- 15 + 9

n
[1] 24

On peut également écrire une expression sans assigner son résultat ou sa valeur à un objet, le résultat est alors affiché à l’écran mais n’est pas stocké dans un objet en mémoire :

(10 + 2) * 5
[1] 60
# Pour enregister le résultat en mémoire, on l'assigne dans un objet, ex :
Mon_objet <- (10 + 2) * 5

1.4.2 La fonction

Le logiciel R dispose de fonctions préprogrammées appelées fonctions primitives ou basiques et regroupées dans le package base qui est automatiquement chargé. Pour connaître toutes les fonctions primitives, utilisez la fonction library(help = “base”):

library(help = "base")

# Quelques exemples...

# class()           Connaitre la classe de données d'un élément
# as.character()    Assigner la class 'caractere' à un élement
# is.numeric()      Tester si un élément est numéric (réponse TRUE ou FALSE) 
# paste()           Coller des chaine de caractère
# unlist()         permet de transformer une liste en vecteur

Pour utiliser une fonction, il suffit d’écrire son nom, puis de spécifier des arguments entre parenthèse.

Exemple de fonctions permettant d’assigner ou de modifier la classe d’un objet :

# Les différentes fonctions permettant de convertir la classe de l'objet 'mon_objet' :
as.vector(x='mon_objet')
as.data.frame(x='mon_objet')
as.matrix(x='mon_objet')
as.array(x='mon_objet')
as.list(x='mon_objet')
as.factor(x='mon_objet')
# Exemple
mon_objet <- "20345"

class(mon_objet)
[1] "character"
mon_objet <- as.numeric(mon_objet)

class(mon_objet)
[1] "numeric"

Une fonction est paramétrable, ajustable à l’aide d’arguments. Très souvent, les arguments d’une fonction sont prédéfinis. Il est donc important de se renseigner sur les différents arguments d’une fonction et ses valeurs paramétrées par défaut. Cependant, certains arguments n’ont pas toujours de valeur prédéfinie et doivent être renseignés.

Exemple avec la fonction mean() :

notes <- c(11,13,15,17,10,8,14,13,12,15,19,NA)

# Il est évidemment obligatoire de spécifier le vecteur de valeurs sur lequel on calcul une moyenne !
mean(notes)
[1] NA

La fonction mean() retourne NA car la série statistique présente une valeur manquante (NA pour Not Available). L’argument na.rm (= FALSE par défaut) permet de ne pas prendre en compte les valeurs manquantes :

# na.rm (= FALSE par défault) permet de prendre en compte ou non les valeurs NA
mean(notes, na.rm = TRUE)
[1] 13.36364
Remarque

En plus des valeurs NA, on trouve aussi des valeurs notées NULL ou encore des valeurs vides. Attention à ne pas confondre les valeurs NA avec les valeurs NaN (Not A Number). Ces valeurs peuvent apparaître à la suite d’erreurs d’encodage, de division par 0 ou bien d’oubli dans la complétion d’un vecteur.

L’utilisateur a également la possibilité de définir ses propres fonctions. Une fonction est mise dans une variable contenant un bloc d’instructions introduit par la commande function(). La syntaxe générale est :

nom_de_fonction <- function(arguments) { instructions }

Exemple :

# Ecriture une fonction
carre <- function(x) {
  y <- x*x
  return(y)
}

# Pour afficher le code source d'une fonction (non primitive), 
# écrire son nom sans parenthèse :
carre
function (x) 
{
    y <- x * x
    return(y)
}
# Utiliser une fonction :
# fonction(argument1=... , argument2=..., argument3=..., ... )

# Exemple :
# carre(x=3) ou plus simplement :
carre(3)
[1] 9

En plus des fonction primitives, des fonctions que vous pouvez vous même créer, il est très simple d’utiliser des fonctions mises à disposition par l’intermédiaire de packages. Pour cela, vous devez d’abord installer le package et charger la library :

# Installation du package
install.packages("foreign")

# Chargement de la library
library(foreign)

# Utilisation de la fonction read.dbf() de la library "foreign"
# L'argument as.is permet de convertir ou non les vecteurs en facteurs
read.dbf("D:/users/geographie/Documents/nom_fichier.dbf", as.is = FALSE)

1.4.3 Le vecteur

Un vecteur permet de regrouper des éléments d’une même classe.

# Joindre des éléments dans un vecteur
mon_vecteur <- c(1,2,3,4,5,6,7,8,9)
mon_vecteur <- c("A","B","C","D","E")
mon_vecteur <- c("nom", "prenom", 10, 20.78, TRUE)
mon_vecteur
[1] "nom"    "prenom" "10"     "20.78"  "TRUE"  
# Créer un séquence de nombres entiers
mon_vecteur <- c(1:7)
mon_vecteur
[1] 1 2 3 4 5 6 7
# Ajouter un élément à un vecteur
mon_vecteur_new <- c(mon_vecteur, "Un Élément Supplémentaire")

# Interroger les éléments d'un vecteur -> mon_vecteur[element]
# Elément 2
mon_vecteur[2]
[1] 2
# Eléments 2 à 4
mon_vecteur[2:4]
[1] 2 3 4
# Eléments 2 et 5
mon_vecteur[c(2,5)]
[1] 2 5

1.4.4 Le data frame

Un data frame est utilisé pour stocker une table de données. Il s’agit d’une liste de vecteurs de même longueur.

# Construction de trois vecteurs
personne <- c('John Doe','Peter Gynn','Jolie Hope','John snow')
salaire <- as.integer(c(21000, 23400, 26800, 32700))
date <- as.Date(c('2010-11-1','2008-3-25','2007-3-14', '1678-1-23'))

# Construction du data.frame à partir de trois vecteurs de même longueur
mon_tableau <- data.frame(personne, salaire, date)
mon_tableau
    personne salaire       date
1   John Doe   21000 2010-11-01
2 Peter Gynn   23400 2008-03-25
3 Jolie Hope   26800 2007-03-14
4  John snow   32700 1678-01-23
# Ajouter une variable
mon_tableau$New_col_1 <- "mon_texte"
mon_tableau$New_col_2 <- c(1,2,3,4)
mon_tableau
    personne salaire       date New_col_1 New_col_2
1   John Doe   21000 2010-11-01 mon_texte         1
2 Peter Gynn   23400 2008-03-25 mon_texte         2
3 Jolie Hope   26800 2007-03-14 mon_texte         3
4  John snow   32700 1678-01-23 mon_texte         4
# Interroger les éléments d'un tableau -> mon_tableau[ligne,colonne]
# Ligne 2
mon_tableau[2,]
    personne salaire       date New_col_1 New_col_2
2 Peter Gynn   23400 2008-03-25 mon_texte         2
# Colonnes 1 et 3
mon_tableau[,c(1,3)]
    personne       date
1   John Doe 2010-11-01
2 Peter Gynn 2008-03-25
3 Jolie Hope 2007-03-14
4  John snow 1678-01-23
# Colonne 'personne'
mon_tableau$personne
[1] "John Doe"   "Peter Gynn" "Jolie Hope" "John snow" 
# Ligne 4 & colonne 'personne' - method 1
mon_tableau[4,"personne"]
[1] "John snow"
# Ligne 4 & colonne 'personne' - method 2
mon_tableau$personne[4]
[1] "John snow"

1.4.5 La liste

Une liste est un vecteur d’objets. Elle permet de stocker des valeurs de différents types dans un seul objet.

ma_fonction <- function() {cat("hello")}
mon_vecteur1 <- c('John Doe','Peter Gynn','Jolie Hope','John snow')
mon_vecteur2 <- as.Date(c('2010-11-1','2008-3-25','2007-3-14', '1678-1-23'))
mon_tableau <- data.frame(mon_vecteur1, mon_vecteur2)

# Création d'une liste
ma_liste <- list(ma_fonction, mon_vecteur1, mon_vecteur2,mon_tableau)
ma_liste
[[1]]
function () 
{
    cat("hello")
}

[[2]]
[1] "John Doe"   "Peter Gynn" "Jolie Hope" "John snow" 

[[3]]
[1] "2010-11-01" "2008-03-25" "2007-03-14" "1678-01-23"

[[4]]
  mon_vecteur1 mon_vecteur2
1     John Doe   2010-11-01
2   Peter Gynn   2008-03-25
3   Jolie Hope   2007-03-14
4    John snow   1678-01-23
# Ajouter un élément à une liste
ma_liste[[length(ma_liste) + 1]] <- "J'ajoute un objet à ma liste"


# Interroger les objets d'une liste -> ma_list[[élement]][sous element]
# Objet 1
ma_liste[5]
[[1]]
[1] "J'ajoute un objet à ma liste"
# Objets 2 et 3
ma_liste[c(2,3)]
[[1]]
[1] "John Doe"   "Peter Gynn" "Jolie Hope" "John snow" 

[[2]]
[1] "2010-11-01" "2008-03-25" "2007-03-14" "1678-01-23"
# Tous les objets sauf le 1 et le 4
ma_liste[-c(1,4)] 
[[1]]
[1] "John Doe"   "Peter Gynn" "Jolie Hope" "John snow" 

[[2]]
[1] "2010-11-01" "2008-03-25" "2007-03-14" "1678-01-23"

[[3]]
[1] "J'ajoute un objet à ma liste"
# Elément 2 de l'objet 3
ma_liste[[3]][2]
[1] "2008-03-25"

1.4.6 La matrice

Une matrice est un tableau d’objet de même type, à double entrée. Le remplissage s’effectue en colonnes.

ma_matrice <- matrix(c(1:16), nrow=4, ncol=4) 

# On navigue dans une matrice de la même façon que dans un data frame -> ma_matrice[ligne, colonne]
ma_matrice[4,3]
[1] 12

De nombreuses opérations et fonctions primitives sont applicables à cet objet. Quelques exemples :

# Multiplication de matrice, élément par élément.
ma_matrice * ma_matrice 
     [,1] [,2] [,3] [,4]
[1,]    1   25   81  169
[2,]    4   36  100  196
[3,]    9   49  121  225
[4,]   16   64  144  256
# Transposer la matrice
t(ma_matrice)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
# Sélectionner la diagonale
diag(ma_matrice)
[1]  1  6 11 16
# Moyennes des lignes
rowMeans(ma_matrice)
[1]  7  8  9 10
# Sommes des colonnes
colSums(ma_matrice)
[1] 10 26 42 58

1.4.7 Le Simple Feature data frame

L’objet sf est en quelque sorte une table de données géographiques. Il permet de gérer de l’information spatiale. Il s’agit tout simplement d’un dataframe qui stocke également des géométries (coordonnées).

Un objet sf se présente comme un tableau de données data.frame, donc comme une table attributaire, à laquelle on ajoute une colonne geom ou “geometry spécifique”, de classe sfc (simple feature column) contenant les géométries (simple feature geometry). Chaque ligne, chaque individu est appelé simple feature.

Dans l’écosystème R, le data.frame est conçu comme une structure de vecteurs. On peut donc effectuer sur les objets sf les même manipulations que l’on fait sur les vecteurs et tableaux dans R.

La colonne contenant les géométries peut quant à elle prendre les types de géométrie traditionnels pris en charge par les GeoJSON :

type description
POINT géométrie à zéro dimension contenant un seul point
LINESTRING séquence de points reliés par des morceaux de lignes droites qui ne se coupent pas entre elles ; géométrie unidimensionnelle
POLYGON Géométrie à aire positive (bidimensionnelle) ; une séquence de points forme un anneau fermé, non auto-intersecté ; le premier anneau désigne l’anneau extérieur, zéro ou plusieurs anneaux suivants désignent des trous dans cet anneau extérieur
MULTIPOINT ensemble de points ; un MULTIPOINT est simple si aucun des points du MULTIPOINT n’est égal.
MULTILINESTRING ensemble de LINESTRING
MULTIPOLYGON ensemble de POLYGON
GEOMETRYCOLLECTION ensemble de géométries de tout type sauf GEOMETRYCOLLECTION

Cette colonne se prête aux géotraitements typiques d’un SIG comme le buffer, l’intersection ou l’agrégation.

# Création d'un vecteur de nombre (1 à 10)
ID <- seq(1:10)
# Création d'un vecteur de lettres (a à j)
name <- letters[1:10]
latitude <- c(48.84905, 48.85217, 48.83349, 48.86528, 48.86409, 48.85176, 48.85207, 48.88334, 48.85758, 48.87391)
longitude <- c(2.331454, 2.347332, 2.318518, 2.371150, 2.356515, 2.299024, 2.358712, 2.333936, 2.352751, 2.343179)

mes_donnees <- data.frame(ID, name, latitude, longitude)

library(sf)
mes_donnees_SF <- st_as_sf(mes_donnees, coords = c("longitude", "latitude"), crs = 4326, agr = "constant")
mes_donnees_SF
Simple feature collection with 10 features and 2 fields
Attribute-geometry relationships: constant (2)
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 2.299024 ymin: 48.83349 xmax: 2.37115 ymax: 48.88334
Geodetic CRS:  WGS 84
   ID name                  geometry
1   1    a POINT (2.331454 48.84905)
2   2    b POINT (2.347332 48.85217)
3   3    c POINT (2.318518 48.83349)
4   4    d  POINT (2.37115 48.86528)
5   5    e POINT (2.356515 48.86409)
6   6    f POINT (2.299024 48.85176)
7   7    g POINT (2.358712 48.85207)
8   8    h POINT (2.333936 48.88334)
9   9    i POINT (2.352751 48.85758)
10 10    j POINT (2.343179 48.87391)
# Interroger un objet sf
# Fonctionne comme pour un data frame pour les différentes variables
# Colonne 'ID'
mes_donnees_SF$ID
 [1]  1  2  3  4  5  6  7  8  9 10
# Colonne ID, ligne 3
mes_donnees_SF$name[3]
[1] "c"
# Geometrie de l'entités 3
mes_donnees_SF$geometry[3]
Geometry set for 1 feature 
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 2.318518 ymin: 48.83349 xmax: 2.318518 ymax: 48.83349
Geodetic CRS:  WGS 84
# Affichage des geometries avec plot()
plot(st_geometry(mes_donnees_SF))

1.4.8 Le facteur

Un facteur (factor) est un vecteur contenant uniquement certaines valeurs prédéfinies. Les valeurs pré-définies sont appelées des levels.

my_factor <- sample(x = c("North", "East", "South", "West"), size = 13, replace = TRUE)
my_factor
 [1] "West"  "East"  "East"  "West"  "West"  "North" "North" "North" "West" 
[10] "North" "North" "West"  "West" 
# Les éléments sont considérés comme caractère
class(my_factor)
[1] "character"
# Conversion en facteur
my_factor <- factor(my_factor)

# Comment se structure le facteur
str(my_factor)
 Factor w/ 3 levels "East","North",..: 3 1 1 3 3 2 2 2 3 2 ...
# Interroger les éléments d'un factor -> factor[element]

# levels() permet d'obtenir la liste des valeurs :
levels(my_factor)
[1] "East"  "North" "West" 
# Compte du nombre d'éléments par level
summary(my_factor)
 East North  West 
    2     5     6 
# Elément 8
my_factor[8]
[1] North
Levels: East North West
# Eléments 7 à 13, avec uniquement les levels présents
my_factor[7:13, drop=TRUE]
[1] North North West  North North West  West 
Levels: North West

1.5 Les opérateurs

1.5.1 Arithmétiques

# Addition
5 + 5
[1] 10
# Soustraction
5 - 5
[1] 0
# Division
5 / 5
[1] 1
# Multiplication
5 * 5
[1] 25
# Exposant
5^5
[1] 3125

1.5.2 Relationnel

  <    # inférieur à 
  >    # supérieur à 
  <=   # inférieur ou égal à 
  >=   # supérieur ou égal à 
  ==   # égal 
  !=   # différent 
  %in% # Test de présence entre deux vecteurs
# Exemple
5 == 5
[1] TRUE
5 != 5
[1] FALSE
c(1,2,3) %in% c(2,7,5) 
[1] FALSE  TRUE FALSE

1.5.3 Logique

  !         # Négation
  &, &&     # ET 
  |, ||     # OU inclusif
  xor(,)    # OU exclusif (retournera TRUE si l'une ou l'autre mais pas les deux sont vraies)
  is.na()   # Valeur manquante ?
  is.null() # Valeur Null ?
  is.character() # Caractère ?
  is.numeric() # Numérique ?
# Exemples

# Selection dans un data frame avec plusieus conditions (ET)
mtcars[mtcars$mpg %in% c(21.0,14.3,22.8,19.2) & mtcars$hp != 123 & mtcars$wt >= 3, ]
                  mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Duster 360       14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 230         22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Pontiac Firebird 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
# Selection dans un data frame avec plusieus conditions (OU)
mtcars[mtcars$mpg %in% c(21.0,14.3,22.8,19.2) | mtcars$hp != 123 | mtcars$wt >= 3, ]
                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
# Test valeurs NA (différent de NA ?) dans la variable mtcars$mpg
!is.na(mtcars$mpg)
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[31] TRUE TRUE
# Renvoie les valeurs des index correspondant à l'affirmation
mtcars$mpg[7] <- NA
!is.na(mtcars$mpg)
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
[13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
[25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

1.6 Les packages

R fourni directement un important nombre de fonctions pré-installées, stockées dans ce qui est appelé le R Base Package. Il n’est pas nécessaire de les installer ou de les charger, elles sont immédiatement utilisables. À ce jour, 2391 fonctions sont proposées par le le R-base.

Les fonctions du r-base permettent d’effectuer les manipulations de données les plus classiques. Pour effectuer des traitements plus spécifiques, il est nécessaire d’installer des packages mis à disposition par d’autres utilisateurs sur le CRAN : The Comprehensive R Archive Network.
Les packages sont des collections de fonctions, associées à de la documentation et parfois même à des données. Le 03 sept. 2025, 22653 packages supplémentaires sont mis à disposition sur le CRAN. Tous les packages disponibles sur le CRAN ont été contrôlés. Leur fonctionnement technique (uniquement) est garanti, car il s’agit d’un dépôt officiel de packages.

Il est également possible d’installer des packages en cours de développement et mise à disposition sur un GIT ou d’installer un package stocké en .tarou .gz sur votre machine.

Installer un package en langage R :

# Pour les packages disponibles sur le CRAN :
install.packages("mapsf") # Installer un package
update.packages("mapsf")  # Mettre à jour un package

# Pour obtenir le chemin de la librairie contenant les packages installés
.libPaths() 
# Pour voir tous les packages installés
library()   

# Pour les packages stockés en local et compressés en tar.gz. Ex (NOT RUN) :
install.packages("C:\\RJSONIO_0.2-3.tar.gz", repos = NULL, type="source")

# Pour les packages en cours de développement sur un GIT,
# il est nécessaire d'installer et de charger le package remotes :
install.packages("remotes")
library(remotes)
install_github("riatelab/MTA")

Une fois installé, un package doit être chargé à chaque nouvelle session de R pour être utilisé. A chaque package est systématiquement associée de la documentation permettant de comprendre son contenu et aider à sa prise en main.

# Charger un package pour en utiliser ses fonctions
library(mapsf)  

# Utiliser directement une fonction d'un package précis
mapsf::mf_map()

# Pour charger des données implémentées dans un package
data(Nom_objet)

L’interface RStudio permet également l’installation et le chargement manuel des packages :

Pour supprimer un package, vous pouvez utiliser la fonction suivante :

remove.packages("mapsf")

1.7 Aide et documentation

Il y a plusieurs façons d’obtenir de l’aide avec R studio. Vous pouvez utiliser l’onglet d’aide proposé par Rstudio et accéder à la documentation d’une fonction :

Il est possible d’obtenir de la documentation en utilisant des fonctions, Ex :

# Documentation des packages
help("mapsf") 

# Accèder à la documentation d'une fonction
?mf_map

# Accèder à une vignette (falcutatif) de package
vignette(topic = "mapsf", package = "mapsf")

# Accèder à une cheatsheet (falcutatif) de package
vignette(topic = "cheatsheet", package = "cartography") 

# Chercher documentation par mot clé
help.search("Map")

Exemple de la cheatsheet (antisèche) du package sf (page 1/2) :

Ne négligez pas le service d’auto-complétion proposé par RStudio. C’est un véritable assistant de programmation. Il permet par exemple de s’assurer du bon orthographe d’un objet ou d’une fonction ou de connaître les différents arguments possibles d’une fonction. Pour cela il suffit d’utiliser la touche tab lors de la saisie. RStudio vous proposera alors les possibilités qui s’offrent à vous.

Enfin, internet est une ressource documentaire très riche pour R. Vous y trouverez toujours une réponse à vos questions, et presque toujours en français !

1.8 Règles de codage

Les règles de codage permettent d’écrire un code plus clair et plus lisible pour soi et pour les autres. Vous pourrez trouver plusieurs propositions de coding style car il n’existe pas de style officiel pour le logiciel R. Quelque soit le style choisi l’idée est de conserver le même tout au long d’un programme.
Voir par exemple :

Trois règles font tout de même l’unanimité :

  • Eviter les lignes de plus de 80 caractères.
  • Utiliser un espace avant et après les opérateurs :
# Préférez
x  <-  12
# à
x<-12

# Préférez
average <- mean(feet / 12 + inches,
                na.rm = TRUE)
# à
average<-mean(feet/12+inches,na.rm=TRUE)
  • Eviter les lignes avec plus d’une opération :
### Il est possible d'écrire plusieurs opération sur une me ligne, en les séparant d'un ;
# Exemple
notes <- c(4,2,8,6,5,9,3,2,5,6); mean(notes); sd(notes)

# Mais cela est à proscrire.
# Pour plus de visibilité, préférez :
notes <- c(4,2,8,6,5,9,3,2,5,6)

mean(notes)

sd(notes)

L’intégration de commentaire dans le code est également une pratique appréciée. Pour cela, insérer un # en début de ligne.

# Les caractères suivants seront considérés comme du commentaire
# Vous pouvez écrire ce que vous voulez, mais toujours précédé d'un #


# une chaîne de 5# (#####) permet de créer de bloc de code dépliable :

###### 
mean(c(1,7,3,2,8,9,2,3))

Ces règles de codages sont à appliquer durant les exercices !

2 Prise en main

  1. Créez un nouveau projet à l’emplacement de votre choix (cf. Les projets).
  2. Téléchargez ces données de recensement (INSEE, 2016) pour les communes de la Martinique en 2011 et 2016, associées à une couche géographique (IGN - BD ADMIN EXPRESS, 2016).
  3. Décompressez l’archive à la racine de votre répertoire projet.
  4. Créez un nouveau ficher .R (File > New File > R Script), puis enregistrez-le. Vous pourrez ainsi écrire du code R dans ce fichier, et sauvegarder votre travail.

2.1 Import/export de données

De nombreuses fonctions (primitives ou non) peuvent être utilisées pour importer et exporter des données de différents formats.

2.1.1 Import

### IMPORTER
read.table() # Importer une table (format multiple)
read.csv()   # Fichier csv
read.xlsx()  # Fichier Excel = library(xlsx) 
read_sas()   # Fichier sas = library(haven)
read.dbf()   # Fichier dbf = library(foreign)
st_read()    # Données géographiques (shape, GeoJson...) = library(sf)

Pour que l’import soit correct, il est souvent nécessaire de renseigner un certain nombre d’arguments, comme par exemple :

header = valeur logique qui indique si la première ligne du fichier importé contient les noms des variables. sep = Indique le séparateur de champ du fichier. stringsAsFactor = Le données de type caractère sont transformées (par défaut) en facteur. Encoding = Indique l’encodage utilisé pour les chaînes de caractères.

# Import d'un fichier 
# not run
Mon_Objet <- read.table("/data/user/documents/mes.donnes.csv"), header=TRUE, sep=",", 
stringsAsFactors=FALSE, encoding="UTF-8")

Il est également possible de télécharger un fichier en ligne, avec la fonction suivante :

# Télécharger un fichier
download.file()

# Décompressez une archive
?unzip()

2.1.2 Export

### EXPORTER

## Table de données
write.table(Mon_Objet, "c:/mydata.txt", sep="\t") 

# format csv
write.csv(Mon_Objet, file = "MyData.csv")

# format Excel -> library(xlsx)
write.xlsx(Mon_Objet, "c:/mydata.xlsx")

# format sas, spss... -> library(foreign)
write.foreign(Mon_Objet, "c:/mydata.txt", "c:/mydata.sas",   package="SAS")
write.foreign(Mon_Objet, "c:/mydata.txt", "c:/mydata.sps",   package="SPSS")

# format shape
st_write()

2.1.3 Image

Les représentations graphiques peuvent également être exportées sous différents formats :

## Figures plot() 
# format jpeg
jpeg()
# format png
png()
# format pdf
pdf()

# Exemple d'enregistrement d'une figure :
jpeg('rplot.jpg')
plot(runif(10, 1, 100),runif(10, 1, 100))
dev.off()

2.1.4 Exercice

Importez le fichier INSEE_COM_972.csv, et stockez-le dans un objet.

# Fonctions possibles
read.csv()
read.table()

# Quelques arguments utiles...
header=TRUE
sep=","
stringsAsFactors=FALSE

2.2 Interroger un objet

Pour les exemples ci-dessous, l’objet dataframe mtcars est utilisé. Il s’agit d’un exemple de data frame implanté dans R.

# Pour visualiser le data frame
View(mtcars)
# Pour un aperçu rapide dans la console
str(mtcars)
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 NA 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

Ces deux fonctions sont directement accessibles en clic-bouton depuis l’interface Rstudio. Il suffit de cliquer sur l’objet dans l’onglet Environnement situé en haut à droite de l’IDE Rstudio (équivalent à View()) ou sur la flèche à gauche du nom de l’objet (équivalent à str()).

# Visualiser les premiers éléments (6 par défaut) de l'objet
head(mtcars)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
# Visualiser les derniers éléments (6 par défaut) de l'objet
tail(mtcars)
                mpg cyl  disp  hp drat    wt qsec vs am gear carb
Porsche 914-2  26.0   4 120.3  91 4.43 2.140 16.7  0  1    5    2
Lotus Europa   30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
Ford Pantera L 15.8   8 351.0 264 4.22 3.170 14.5  0  1    5    4
Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.5  0  1    5    6
Maserati Bora  15.0   8 301.0 335 3.54 3.570 14.6  0  1    5    8
Volvo 142E     21.4   4 121.0 109 4.11 2.780 18.6  1  1    4    2
# Statistiques basiques
summary(mtcars)
      mpg             cyl             disp             hp       
 Min.   :10.40   Min.   :4.000   Min.   : 71.1   Min.   : 52.0  
 1st Qu.:15.65   1st Qu.:4.000   1st Qu.:120.8   1st Qu.: 96.5  
 Median :19.20   Median :6.000   Median :196.3   Median :123.0  
 Mean   :20.28   Mean   :6.188   Mean   :230.7   Mean   :146.7  
 3rd Qu.:22.80   3rd Qu.:8.000   3rd Qu.:326.0   3rd Qu.:180.0  
 Max.   :33.90   Max.   :8.000   Max.   :472.0   Max.   :335.0  
 NA's   :1                                                      
      drat             wt             qsec             vs        
 Min.   :2.760   Min.   :1.513   Min.   :14.50   Min.   :0.0000  
 1st Qu.:3.080   1st Qu.:2.581   1st Qu.:16.89   1st Qu.:0.0000  
 Median :3.695   Median :3.325   Median :17.71   Median :0.0000  
 Mean   :3.597   Mean   :3.217   Mean   :17.85   Mean   :0.4375  
 3rd Qu.:3.920   3rd Qu.:3.610   3rd Qu.:18.90   3rd Qu.:1.0000  
 Max.   :4.930   Max.   :5.424   Max.   :22.90   Max.   :1.0000  
                                                                 
       am              gear            carb      
 Min.   :0.0000   Min.   :3.000   Min.   :1.000  
 1st Qu.:0.0000   1st Qu.:3.000   1st Qu.:2.000  
 Median :0.0000   Median :4.000   Median :2.000  
 Mean   :0.4062   Mean   :3.688   Mean   :2.812  
 3rd Qu.:1.0000   3rd Qu.:4.000   3rd Qu.:4.000  
 Max.   :1.0000   Max.   :5.000   Max.   :8.000  
                                                 
# classe/type des éléments/objets
class(mtcars)
[1] "data.frame"
# Longueur = nombre d'éléments de l'objet
length(mtcars)
[1] 11
# Pour les objets à plusieurs dimensions :
# Noms des colonnes
colnames(mtcars)
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
[11] "carb"
# Noms des lignes
row.names(mtcars)
 [1] "Mazda RX4"           "Mazda RX4 Wag"       "Datsun 710"         
 [4] "Hornet 4 Drive"      "Hornet Sportabout"   "Valiant"            
 [7] "Duster 360"          "Merc 240D"           "Merc 230"           
[10] "Merc 280"            "Merc 280C"           "Merc 450SE"         
[13] "Merc 450SL"          "Merc 450SLC"         "Cadillac Fleetwood" 
[16] "Lincoln Continental" "Chrysler Imperial"   "Fiat 128"           
[19] "Honda Civic"         "Toyota Corolla"      "Toyota Corona"      
[22] "Dodge Challenger"    "AMC Javelin"         "Camaro Z28"         
[25] "Pontiac Firebird"    "Fiat X1-9"           "Porsche 914-2"      
[28] "Lotus Europa"        "Ford Pantera L"      "Ferrari Dino"       
[31] "Maserati Bora"       "Volvo 142E"         
# Dimension de l'objet
dim(mtcars)
[1] 32 11
# Nombre de colonnes
ncol(mtcars)
[1] 11
# Nombre de lignes
nrow(mtcars)
[1] 32

2.2.1 Exercice

Visualisez et interrogez votre data frame, en ligne de code ET depuis l’interface RStudio.

# Fonctions possibles :
View()
head()
dim()
str()
summary()
class()
colnames()
...

Vérifiez le type de données stocké pour chaque variable. Si nécessaire, corrigez la classe de données des variablesCODGEO,’DEP’, ‘REG’, ‘CATAEU2010de votre data frame comportant les données de recensement. N’oubliez pas d’assigner le résultat de la conversion :

# Convertissez le type de données d'une variable
Mon_Objet$xxxx <- as.character(Mon_Objet$xxxx)

Créez une nouvelle variable contenant la part de la population âgée de 0 à 14 ans en 2016 (P16_POP0014 / P16_POP * 100) :

# Assigner les valeur dans une nouvelle colonne
mon_tableau$new_var <- ... ?

2.3 Sélection par attributs

Comme pour toutes les opérations dans R, il existe plusieurs solutions. Exemple :

2.3.1 Méthode 1 - Base

# df[ligne, colonne]
mtcars[mtcars$cyl==4 & mtcars$wt > 3,  c(1:7) ]
           mpg cyl  disp hp drat   wt qsec
Merc 240D 24.4   4 146.7 62 3.69 3.19 20.0
Merc 230  22.8   4 140.8 95 3.92 3.15 22.9

2.3.2 Méthode 2 - Fonction primitive

# subset()
subset(mtcars, cyl==4 & mtcars$wt > 3, select=c(1:7))
           mpg cyl  disp hp drat   wt qsec
Merc 240D 24.4   4 146.7 62 3.69 3.19 20.0
Merc 230  22.8   4 140.8 95 3.92 3.15 22.9

2.3.3 Méthode 3 - Package dplyr

# filter() du package 'dplyr'
library(dplyr)
mtcars %>% 
  select(1:6) %>%
  filter(cyl==4, wt > 3)
           mpg cyl  disp hp drat   wt
Merc 240D 24.4   4 146.7 62 3.69 3.19
Merc 230  22.8   4 140.8 95 3.92 3.15

2.3.4 Exercice

Sélectionnez les communes isolées hors influence des pôles (CATAEU2010 == 400) de plus de 2000 habitants en 2016 (P16_POP).

# Une de solution possible :
tableau[tableau$CATAEU2010==400 & ... , ]

Enregistrez le résultat de votre sélection par attribut dans un nouvel objet.

2.4 Jointure

La jointure, opération classique en géomatique, est très facile à réaliser avec R.

# Construction de deux dataframe avec un identifiant commun
ID <- c("1", "2", "3", "4")
Prenom <- c('John','Peter','Jolie','John')
Nom <- c('Doe','Gynn','Hope','snow')

# Dans la console, la chaîne de caractère "snow" correspond aussi à une couleur

# Dataframe 1
mon_tab_1 <- data.frame(ID, Prenom)

# Dataframe 2
mon_tab_2 <- data.frame(ID, Nom)

# Jointure des deux objets avec la fonction merge()
merge(mon_tab_1, mon_tab_2, by="ID")
  ID Prenom  Nom
1  1   John  Doe
2  2  Peter Gynn
3  3  Jolie Hope
4  4   John snow

Cela fonctionne également entre un objet sf (couche géographique) et un dataframe.

2.4.1 Exercice

Chargez la couche géographique martinique.shp, et stockez-le dans un objet.

# Utilisez la fonction du package sf :
st_read()

Réalisez une jointure entre la couche géographique et votre tableau de données, en assignant le résultat dans un nouvel objet. Utilisez le code INSEE des communes pour la jointure

# Pour réaliser une jointure, utilisez la fonction :
merge()

# Préciser la variable de jointure pour les deux objets avec les arguments :
by.x=
by.y=

2.5 Regroupement

Le regroupement de ligne est une opération récurrente en gestion de base de données. Plusieurs solutions sont possibles :

2.5.1 Méthode 1 - Fonction primitive

# Regroupement des lignes en fonction des valeurs des variables "disp" et "cyl"
# + somme des valeurs de la variable "vs"
aggregate(data = mtcars, disp ~ cyl + vs, sum)
  cyl vs   disp
1   4  0  120.3
2   6  0  465.0
3   8  0 4943.4
4   4  1 1036.2
5   6  1  818.2

2.5.2 Méthode 2 - Package tidyverse

# Package dplyr
# Permet facilement le calcul sur plusieurs champs
library(dplyr)
mtcars %>% 
  group_by(cyl, vs) %>% 
  summarise(sum_disp=sum(disp), 
            moy_hp=mean(hp), 
            nb_element=length(cyl))
# A tibble: 5 × 5
# Groups:   cyl [3]
    cyl    vs sum_disp moy_hp nb_element
  <dbl> <dbl>    <dbl>  <dbl>      <int>
1     4     0     120.   91            1
2     4     1    1036.   81.8         10
3     6     0     465   132.           3
4     6     1     818.  115.           4
5     8     0    4943.  209.          14

2.5.3 Méthode 2 - Package data.table

library(data.table)
mtcars2 <- data.table(mtcars)
mtcars2[, .( sum_disp=sum(disp), moy_hp=mean(hp), nb_element=length(cyl) ), by=list(cyl, vs)]
     cyl    vs sum_disp   moy_hp nb_element
   <num> <num>    <num>    <num>      <int>
1:     6     0    465.0 131.6667          1
2:     4     1   1036.2  81.8000          1
3:     6     1    818.2 115.2500          1
4:     8     0   4943.4 209.2143          1
5:     4     0    120.3  91.0000          1
Remarque

Le package data.table est plutôt utilisé pour les gros volumes de données.

2.5.4 Exercice

Commencez par calculer la somme de la population totale de la Martinique à l’aide la fonction suivante :

sum()

Puis calculez la somme de la population 2016 pour chaque catégorie de commune du zonage en aire urbaine de 2010 (CATAEU2010):

# Une solution
aggregate()

# Nom des variables à utiliser
P16_POP ~ CATAEU2010

2.6 Trier les données

Deux fonctions primitives sont à connaître pour trier des valeurs :

# Fonction sort()
my_vector <- c(7,9,4,5,2,3,6,1)
sort(my_vector)
[1] 1 2 3 4 5 6 7 9
# Fonction order()
mtcars[order(mtcars$cyl, mtcars$disp, decreasing = TRUE), ]
                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Duster 360            NA   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1

Vous devez assigner le résultat dans un objet pour enregistrer le nouvel ordre !

2.6.1 Exercice

Triez votre tableau de données en fonction de la population de 2016 (croissant) :

order()

2.7 Test conditionnel

Un test conditionnel permet d’exécuter une portion de code ou non en fonction du résultat de variables booléennes.

# Test simple
if (condition){action}

# Test avec deux solutions
if (condition){
  action1
} else {
  action2
}
# Exemple
x <- "chaîneDeCaractères"
x <- TRUE
x <- 12

if (is.character(x)){
  
  print("x est une chaîne de caractères")
  
} else {
  
  if (is.numeric(x)) {
    
    print("x est numérique") 
    
  } else {
    
    print("x est bizarre !")
    
  }
}
[1] "x est numérique"

2.7.1 Exercice

Testez si votre tableau de données est bien un objet dataframe, et affichez le résultat dans la console avec la fonction print() :

if (is.data.frame()) { print() } else { print() }

2.8 Boucle itérative

Une boucle est une série d’instructions exécutées jusqu’à ce qu’un résultat particulier soit obtenu ou qu’une condition pré-déterminée soit remplie. Les boucles permettent de ré-utiliser des séries d’instructions et permettent ainsi de limiter le nombre d’instructions.

# Structure d'une boucle
for (variable in vecteur) {
  instruction
}
# Exemple
for (i in 1:5) {
  print(paste0("Passage n°", i))
}
[1] "Passage n°1"
[1] "Passage n°2"
[1] "Passage n°3"
[1] "Passage n°4"
[1] "Passage n°5"

2.9 Fonctions apply

L’utilisation d’une boucle est très fréquente en traitement de données. Une boucle peut permettre d’effectuer des traitements sur des objets de structure multidimensionnelle (data frame, matrice, array, sf…). Mais pour cela, la boucle for n’est pas la technique optimale. Les concepteurs de R ont développé des fonctions spécialement prévues à cet effet.

# Appliquer une fonction sur les lignes :
apply(mtcars,1,mean)
          Mazda RX4       Mazda RX4 Wag          Datsun 710      Hornet 4 Drive 
           29.90727            29.98136            23.59818            38.73955 
  Hornet Sportabout             Valiant          Duster 360           Merc 240D 
           53.66455            35.04909                  NA            24.63455 
           Merc 230            Merc 280           Merc 280C          Merc 450SE 
           27.23364            31.86000            31.78727            46.43091 
         Merc 450SL         Merc 450SLC  Cadillac Fleetwood Lincoln Continental 
           46.50000            46.35000            66.23273            66.05855 
  Chrysler Imperial            Fiat 128         Honda Civic      Toyota Corolla 
           65.97227            19.44091            17.74227            18.81409 
      Toyota Corona    Dodge Challenger         AMC Javelin          Camaro Z28 
           24.88864            47.24091            46.00773            58.75273 
   Pontiac Firebird           Fiat X1-9       Porsche 914-2        Lotus Europa 
           57.37955            18.92864            24.77909            24.88027 
     Ford Pantera L        Ferrari Dino       Maserati Bora          Volvo 142E 
           60.97182            34.50818            63.15545            26.26273 
# Appliquer une fonction sur les colonnes :
apply(mtcars,2,sum)
     mpg      cyl     disp       hp     drat       wt     qsec       vs 
      NA  198.000 7383.100 4694.000  115.090  102.952  571.160   14.000 
      am     gear     carb 
  13.000  118.000   90.000 
# Appliquer une fonction sur chaque item (sortie vector) :
sapply(mtcars, function(x) x/100)
        mpg  cyl  disp   hp   drat      wt   qsec   vs   am gear carb
 [1,] 0.210 0.06 1.600 1.10 0.0390 0.02620 0.1646 0.00 0.01 0.04 0.04
 [2,] 0.210 0.06 1.600 1.10 0.0390 0.02875 0.1702 0.00 0.01 0.04 0.04
 [3,] 0.228 0.04 1.080 0.93 0.0385 0.02320 0.1861 0.01 0.01 0.04 0.01
 [4,] 0.214 0.06 2.580 1.10 0.0308 0.03215 0.1944 0.01 0.00 0.03 0.01
 [5,] 0.187 0.08 3.600 1.75 0.0315 0.03440 0.1702 0.00 0.00 0.03 0.02
 [6,] 0.181 0.06 2.250 1.05 0.0276 0.03460 0.2022 0.01 0.00 0.03 0.01
 [7,]    NA 0.08 3.600 2.45 0.0321 0.03570 0.1584 0.00 0.00 0.03 0.04
 [8,] 0.244 0.04 1.467 0.62 0.0369 0.03190 0.2000 0.01 0.00 0.04 0.02
 [9,] 0.228 0.04 1.408 0.95 0.0392 0.03150 0.2290 0.01 0.00 0.04 0.02
[10,] 0.192 0.06 1.676 1.23 0.0392 0.03440 0.1830 0.01 0.00 0.04 0.04
[11,] 0.178 0.06 1.676 1.23 0.0392 0.03440 0.1890 0.01 0.00 0.04 0.04
[12,] 0.164 0.08 2.758 1.80 0.0307 0.04070 0.1740 0.00 0.00 0.03 0.03
[13,] 0.173 0.08 2.758 1.80 0.0307 0.03730 0.1760 0.00 0.00 0.03 0.03
[14,] 0.152 0.08 2.758 1.80 0.0307 0.03780 0.1800 0.00 0.00 0.03 0.03
[15,] 0.104 0.08 4.720 2.05 0.0293 0.05250 0.1798 0.00 0.00 0.03 0.04
[16,] 0.104 0.08 4.600 2.15 0.0300 0.05424 0.1782 0.00 0.00 0.03 0.04
[17,] 0.147 0.08 4.400 2.30 0.0323 0.05345 0.1742 0.00 0.00 0.03 0.04
[18,] 0.324 0.04 0.787 0.66 0.0408 0.02200 0.1947 0.01 0.01 0.04 0.01
[19,] 0.304 0.04 0.757 0.52 0.0493 0.01615 0.1852 0.01 0.01 0.04 0.02
[20,] 0.339 0.04 0.711 0.65 0.0422 0.01835 0.1990 0.01 0.01 0.04 0.01
[21,] 0.215 0.04 1.201 0.97 0.0370 0.02465 0.2001 0.01 0.00 0.03 0.01
[22,] 0.155 0.08 3.180 1.50 0.0276 0.03520 0.1687 0.00 0.00 0.03 0.02
[23,] 0.152 0.08 3.040 1.50 0.0315 0.03435 0.1730 0.00 0.00 0.03 0.02
[24,] 0.133 0.08 3.500 2.45 0.0373 0.03840 0.1541 0.00 0.00 0.03 0.04
[25,] 0.192 0.08 4.000 1.75 0.0308 0.03845 0.1705 0.00 0.00 0.03 0.02
[26,] 0.273 0.04 0.790 0.66 0.0408 0.01935 0.1890 0.01 0.01 0.04 0.01
[27,] 0.260 0.04 1.203 0.91 0.0443 0.02140 0.1670 0.00 0.01 0.05 0.02
[28,] 0.304 0.04 0.951 1.13 0.0377 0.01513 0.1690 0.01 0.01 0.05 0.02
[29,] 0.158 0.08 3.510 2.64 0.0422 0.03170 0.1450 0.00 0.01 0.05 0.04
[30,] 0.197 0.06 1.450 1.75 0.0362 0.02770 0.1550 0.00 0.01 0.05 0.06
[31,] 0.150 0.08 3.010 3.35 0.0354 0.03570 0.1460 0.00 0.01 0.05 0.08
[32,] 0.214 0.04 1.210 1.09 0.0411 0.02780 0.1860 0.01 0.01 0.04 0.02
# Appliquer une fonction sur chaque item (sortie list)
Resultat_lapply <- lapply(mtcars, function(x) x/100)
Resultat_lapply[1:3]
$mpg
 [1] 0.210 0.210 0.228 0.214 0.187 0.181    NA 0.244 0.228 0.192 0.178 0.164
[13] 0.173 0.152 0.104 0.104 0.147 0.324 0.304 0.339 0.215 0.155 0.152 0.133
[25] 0.192 0.273 0.260 0.304 0.158 0.197 0.150 0.214

$cyl
 [1] 0.06 0.06 0.04 0.06 0.08 0.06 0.08 0.04 0.04 0.06 0.06 0.08 0.08 0.08 0.08
[16] 0.08 0.08 0.04 0.04 0.04 0.04 0.08 0.08 0.08 0.08 0.04 0.04 0.04 0.08 0.06
[31] 0.08 0.04

$disp
 [1] 1.600 1.600 1.080 2.580 3.600 2.250 3.600 1.467 1.408 1.676 1.676 2.758
[13] 2.758 2.758 4.720 4.600 4.400 0.787 0.757 0.711 1.201 3.180 3.040 3.500
[25] 4.000 0.790 1.203 0.951 3.510 1.450 3.010 1.210

2.10 Chaîne de caractères

De nombreuses fonctions primitives existent pour gérer les chaînes de caractères. Quelques exemples :

2.10.1 Concaténer

# Concaténation de chaîne de caractère, AVEC séparateur
paste("Champions", "du", "monde", sep=" ")
[1] "Champions du monde"
# Concaténation de chaîne de caractère, SANS séparateur
paste0("Champions", "du", "monde")
[1] "Championsdumonde"

2.10.2 Gérer la casse

# Gérer la casse
text <- "champion Du MONDEEEEEE !"
# tout en minuscule
tolower(text)
[1] "champion du mondeeeeee !"
# tout en majuscule
toupper(text)
[1] "CHAMPION DU MONDEEEEEE !"

2.10.3 Compter

# Nombre de caractères
nchar(text)
[1] 24

2.10.4 Modifier

# Scinder une chaîne en fonction d'un caractère
strsplit(text, split = " ", fixed = TRUE)
[[1]]
[1] "champion"   "Du"         "MONDEEEEEE" "!"         
# Remplacer un (ou plusieurs) caractère(s) par un autre
gsub("ion", "ionne", text)
[1] "championne Du MONDEEEEEE !"

2.10.5 Package stringr

Si vous souhaitez réaliser des traitements complexes sur des chaînes de caractères, vous pouvez utiliser la librairie de référence stringr qui vous permettra de réaliser des opérations plus complexes. Exemples :

library(stringr)

# Détecter la présence d'un caractère ou d'une chaîne
# Renvoie TRUE ou FALSE
str_detect(text,  "E")

# Position de la première occurrence d'un caractère ou d'une chaîne 
# Renvoie la position du premier et dernier caractère
str_locate(text, "pi")

# Toutes les positions d'un caractère ou d'une chaîne
# Renvoie toutes les positions
str_locate_all(text, "E")

# Extraire un segment de chaîne de caractère
# Renvoie la chaîne de caractère extraite
str_sub(text,  5, 9)

# Suppression des espaces en début et fin de chaîne de caractère
str_trim("  abc    ")

2.10.6 Regex

Il est possible de combiner l’utilisation des expressions régulières avec toutes ces fonctions.

Les expressions régulières, ou plus communément REGEX (contraction de regular expression) permettent de représenter des modèles de chaînes de caractères. Ce sont des outils très puissants et très utilisés : on peut les retrouver dans de nombreux langages comme le PHP, MySQL, Javascript… Si cet outil est très puissant, il est relativement difficile à appréhender au début car les expressions régulières peuvent prendre des formes complexe à interpréter. Ex :

# EXEMPLE d'utilisation d'expression régulière (regex)

# Création d'une vecteur d'adresse mail
# Avec des adresses mail, parfois mal orthographiées
emails_list <- c("louis.laurian@cnrs.fr",
                 "elina.marveaux@cnrs.fr",
                 "louis@gmail", 
                 "blabla.com", 
                 "louis.laurian@riate.fr")


# Expression regex qui répond aux adresses email
regex <- "\\<[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\>"


# Détection des emails corrects présentes dans ma liste d'email
grep(regex, emails_list, ignore.case=TRUE)
[1] 1 2 5

2.10.7 Exercice

Créez une nouvelle colonneNOM” dans votre objet sf, pour y stocker le nom des communes en lettre CAPITALE.

# Fonction à utiliser :
toupper()

2.11 Représentations graphiques

2.11.1 Fonction primitives

Plusieurs fonctions primitives permettent de réaliser des graphiques :

plot()
hist()
barplot()
boxplot()
pie()
lines()
abline()
legend()
# Exemple
hist(mtcars$mpg, 
     breaks=12, 
     col="red",
     xlab= "mpg",
     ylab = "Fréquence",
     main = "Distribution de la série statistique 'mpg'")

Toute une série d’arguments permet d’ajuster les représentations, exemple :

  • axes : Afficher ou non les axes (TRUE ou FALSE)
  • log : Mettre les axes à l’échelle logarithmique (“x”, “y”, “xy”)
  • type : Argument qui contrôle le type d’axe produit (“p”= points, “l” = ligne, “o” = point relier par ligne…)

Plusieurs éléments peuvent être superposés en utilisant l’argumentadd =TRUE”), ex :
- text() : Ajouter du texte
- legend() : Ajouter un légende
- abline() : Ajouter une ligne
- axis() : Ajouter un axe
- …

Il est possible d’afficher plusieurs graphiques en même temps, à l’aide de la fonction par(). Ex :

# Division de la fenêtre graphique en 2 lignes et 2 colonnes
par(mfrow=c(2,2))

# Création de 4 différents graphiques
plot(mtcars$wt, mtcars$mpg, main="Graph 1")
plot(mtcars$wt, mtcars$disp, main="Graph 2")
hist(mtcars$wt, main="Graph 3")
boxplot(mtcars$wt, main="Graph 4")

2.11.2 Plot(sf)

La fonction plot() permet l’affichage d’un objet sf (couche géographique) dans la fenêtre graphique.

library(mapsf)

# Utilisation d'un objet sf stocké dans le package mapsf
mtq <- mf_get_mtq()

# Affichage de l'objet sf
plot(mtq)

Attention, le fonction plot() réalise par défaut une représentation pour chaque variable de l’objet sf.
Pour afficher uniquement la géométrie, il est nécessaire d’utiliser la fonction st_geometry() du package sf :

library(sf)

# Affichage de la géométrie d'un objet sf
plot(st_geometry(mtq))

Pour représenter les valeurs d’une variable de votre objet sf, utilisez la syntaxe suivante :

# Représentation visuelle
plot(mtq["POP"])

Attention, ceci n’est pas une carte ! A n’utiliser que pour explorer les données.

2.11.3 ggplot2

Il existe de très nombreux packages pour réaliser des représentations graphiques (point fort du langage R).

Le plus célèbre est ggplot2. Il permet de réaliser de très nombreux types de représentation graphique. Ce package est développé par Hadley Wickham (Rstudio) et fonctionne avec un syntaxe particulière basée sur la grammaire des graphiques, théorisée par Leland Wilkinson. Exemple :

library(ggplot2)

# Exemple : Density plots
ggplot(mpg, aes(cty)) +
  geom_density(aes(fill=factor(cyl)), alpha=0.8) + 
  labs(title="Density plot", 
       subtitle="City Mileage Grouped by Number of cylinders",
       caption="Source: data R mtcars",
       x="City Mileage",
       fill="# Cylinders")

2.11.4 Exercice

Construisez un histogramme de la variableC16_POP15P_CS7’ (nombre de retraités) .

# Fonction à utiliser :
hist()

Représentez les valeurs de cette variable en aplat de couleur sur la géométrie de votre objet sf.

# Fonction à utiliser :
plot()

2.12 Sauvegarder des objets

Il est possible de supprimer tous les objets crées en cliquant sur l’icône ::: {.cell-output-display} :::

dans la fenêtre de l’espace de travail. Plusieurs fonctions permettent également de gérer les objets. En voici quelques-unes :

# lister tous les objets crées
ls()    

# Supprimer un objet, ex : rm(mon_objet)
rm()    

# Supprimer tous les objets
rm(list=ls()) 

# Sauvegarder un objet dans un fichier (format rds)
saveRDS() 

# Lire un fichier rds pour charger l'objet stocké
readRDS() 

Exemple pratique :

mon_objet <- c("un", "deux", "trois")

# Sauvegarde d'un objet dans un fichier
saveRDS(mon_objet, file="Nom_du_fichier")

# Suppression de l'objet TEMPORAIRE
rm(mon_objet) 

# Lecture du fichier et assignation dans un objet
mon_objet_new <- readRDS("Nom_du_fichier") 

2.12.1 Exercice

Sauvegardez votre objet sf joint aux données de recensement dans le répertoire de votre projet Rstudio.

# Fonction à utiliser :
saveRDS()

Puis, supprimez tous les objets chargés dans votre environnement Rstudio

# Fonctions à utiliser :
rm() et ls()

Enfin, rechargez l’objet enregistré en dur dans votre environnement Rstudio:

# Fonction à utiliser :
readRDS()

2.13 Bonus

R est un langage très polyvalent… Voici un petit exercice pour le prouver :

  1. Trouvez où est mis à disposition le package wordler, développé par David Smith
  2. Installez-le
  3. Essayez-le… Pas plus de 2-3 minutes :-) )
  4. Supprimez le package

3 Statistique univariée

3.1 Vocabulaire

3.1.1 Vocabulaire général

Statistique descriptive

Tout nombre, calculé à propos d’une population et qui contribue à décrire un aspect de cette population, est une statistique. Fréquences, médianes, quartiles, déciles, moyennes, variances, etc. sont des statistiques.
La statistique descriptive regroupe l’ensemble des techniques pour décrire numériquement une distribution.

Population (p) et Individu (i)

Une population est un ensemble d’individus (ou unités statistiques) sur lesquels porte l’étude statistique.

Effectif (N ou n)

Nombre d’individus d’une population(N) ou d’une partie quelconque de cette population(n).

\[N=\sum_{} i\]

Variable (x) ou caractère Une variable est une information dont on recueille (ou observe ou mesure) la valeur sur chaque individu. On parle de variable parce que la valeur de l’information n’est pas la même d’un individu à l’autre. Une variable est quantitative (valeur numérique) ou qualitative :

Une variable est quantitative si elle est mesurable. Ex : Un temps.

Elle est discrète si elle ne prend que des valeurs isolées. Ex : un âge. Elle est continue si elle peut prendre toutes les valeurs comprises entre 2 nombres. Ex : une distance.

Si une variable n’est pas mesurable, elle est dite qualitative. Ex: Une couleur.

Elle est ordinale si on peut comparer/trier les modalités entre elles. Ex : Une appréciation. Elle est binaire si elle n’est composé que de deux modalités. Ex : oui/non. Elle est dite nominale dans les autres cas. Ex : Une forme.

Il faut bien distinguer la nature de la variable de son format de stockage (classe de donnée), numérique ou alphanumérique. Une variable qualitative peut aussi bien être codée avec des caractères alphanumériques qu’avec des caractères numériques (Ex : “Homme” ou 0 / “Femme” ou 1). Une variable quantitative peut être codée avec des caractères numériques aussi bien qu’avec des caractères alphanumériques : (Ex : “dix sept” ou 17 ).

Distribution

La distribution des individus selon une (ou deux) variables, est la répartition de l’effectif (n) des individus (i) par valeur ou classe de valeur.

Fréquence (f) ou proportion

Rapport entre un effectif (n) particulier d’individus et l’effectif total (N).

\[f(n)=\frac{n}{N}\]

3.1.2 Valeurs centrales

Moyenne

Valeur uniforme que devrait présenter chaque individu d’un ensemble (population ou échantillon) pour que le total de l’ensemble soit inchangé.

\[\bar{x}=\frac{\sum{xi}}{N}\]

Mode

Le mode (ou valeur dominante) est la valeur la plus représentée d’une variable quelconque dans une population donnée. Une répartition peut être uni-modale ou multimodale (bimodale, tri-modale…) si deux ou plusieurs valeurs de la variable considérée émergent également. Une distribution sans aucun mode est appelée distribution uniforme.

Médiane, quartiles, déciles et centiles

Ces valeurs correspondent respectivement à une proportion de l’effectif des individus rangés par valeurs croissantes.

  • Médiane : valeur qui divise la série statistique en deux (50 %)
  • Quartiles : valeurs qui divisent la série statistique en quatre (Q1=25%, Q2=50%, Q3=75%)
  • Déciles : valeurs qui divisent la série statistique en dix (10% à 90%)
  • Centiles : valeurs qui divisent la série statistique en cent (1% à 99%)

3.1.3 Paramètres de dispersion

Amplitude

Longueur de l’intervalle entre la valeur minimum et maximum.

Intervalle interquartile

Basé sur les quantiles, l’intervalle inter-quartile (Q3-Q1) est un paramètre de dispersion absolue qui correspond à l’étendue d’une distribution une fois que l’on a retiré les 25% des valeurs les plus faibles et les 25% des valeurs les plus fortes.

Écart absolu moyen

Moyenne de la valeur absolue des écarts à la moyenne. Autrement dit, c’est la distance moyenne à la moyenne.

Écart absolu médian

Moyenne des écarts à la médiane.

Variance(σ2) et écart-type(σ)

Indicateurs de la dispersion des valeurs des individus autour de la moyenne. La variance est la moyenne des carrés des écarts à la moyenne. L’écart-type est sa racine carrée. Ce sont des paramètres de dispersion.

\[\sigma^x = \sqrt{ \frac{\sum_{i=1}^{n}(x_i - \mu)^2} {n}} \]

Coefficient de variation

Le coefficient de variation (CV) est le rapport de l’écart-type à la moyenne. Le coefficient de variation, également nommé écart type relatif, est une mesure de dispersion relative. Plus la valeur du coefficient de variation est élevée, plus la dispersion autour de la moyenne est grande. Il est généralement exprimé en pourcentage. Sans unité, il permet la comparaison de distributions de valeurs dont les échelles de mesure ne sont pas comparables.

\[CV = \frac{\sigma }{\mu } \]

3.1.4 Discrétiser une distribution

Discrétiser revient à rendre discret des valeurs continues. Cela consiste à classer les valeurs quantitatives d’une série statistique par intervalle de valeur selon des critères justifiables afin d’en améliorer la lecture.

L’ensemble des classes (intervalles de valeurs) créé forme ainsi une partition de toutes les valeurs possibles de la variable.

Exemple :
Il est par exemple possible de discrétiser les valeurs d’un variable s’échelonnant de 1 à 25, en construisant les classes suivantes : [min à 5] - [6 à 10] - [11 à 15] - [16 à 20] - [21 à max]

3.1.5 Normaliser une distribution

La normalisation d’une (ou plusieurs) série(s) de données est nécessaire quand l’incompatibilité des unités de mesures entre les variables peut affecter les résultats sans apporter d’interprétations claires. Elle permet d’ajuster une série (vecteur) de valeurs suivant une fonction de transformation pour les rendre comparables avec quelques points de référence spécifiques.

Deux exemple de normalisation :

  • Transformation en pourcentage (en ligne, en colonne ou les deux):

  • Standardisation (centrer-réduire):

Il s’agit d’un centrage par rapport à la moyenne puis d’une réduction par rapport à l’écart-type :

\[Y_{i} =\frac{X_{i} - \bar{x}}{\sigma^x }\]

3.2 Résumer une variable

Avant de décrire, analyser une ou plusieurs variables statistiques, il est indispensable de contrôler et d’explorer les données. Cela permet de détecter des incohérences et les caractéristiques des données étudiées, afin de correctement les traiter.

Comment se structure la table de données ? Est-elle correctement construite et renseignée ?
Comment sont nommées les individus et les variables ?
Quelle est la classe de données des différentes variables (numérique, chaîne de caractère, booléenne…) ?
Quelles sont les types des variables stockées (quantitative, qualitative…) ?

Dans un premier temps, nous utiliserons des données mises à disposition par le package questionr, qui contient des variables qualitatives. Installez ce package, puis chargez la librairie et les données associéeshdv2003” :

# install.packages("questionr")
library(questionr)

# Chargement des données fournies par le package questionr
data(hdv2003)

Prenez quelques minutes pour explorer ce tableau de données. Vous pouvez utiliser l’interface Rstudio, mais également un certain nombre de fonctions primitives :

# Quelques exemple
View()
str()
colnames()
row.names()
dim()
class()
is.na()
colSums(is.na())

Les données vous semblent-elles cohérentes et correctement typées dans R ?

3.2.1 La distribution

Lorsque l’on étudie une variable, on s’intéresse rapidement à la distribution de sa série statistique. Pour cela, on peut calculer la table de fréquence (nombre d’individus par valeur, classe de valeur ou par modalité). Sous R, le procédé est différent selon le type de variable étudié :

3.2.1.1 Variable qualitative : fréquence des individus par modalités.

Utilisez les fonctions table() ou prop.table() :

# Nb d'individus par modalité
table(hdv2003$occup)

Exerce une profession               Chomeur       Etudiant, eleve 
                 1049                   134                    94 
             Retraite   Retire des affaires              Au foyer 
                  392                    77                   171 
        Autre inactif 
                   83 
# Effectifs relatifs (%)
prop.table(table(hdv2003$occup))

Exerce une profession               Chomeur       Etudiant, eleve 
               0.5245                0.0670                0.0470 
             Retraite   Retire des affaires              Au foyer 
               0.1960                0.0385                0.0855 
        Autre inactif 
               0.0415 

Pour représenter graphiquement votre table de fréquence :

# Utilisation d'une librairie de palettes de couleur
# install.packages("RColorBrewer")
library("RColorBrewer")

# Histogramme
barplot(table(hdv2003$occup), col=brewer.pal(n = 9,  "Paired"), las=2 ,cex.names=0.6)

3.2.1.2 Variable quantitative: fréquence des individus par classe.

Pour faciliter l’exploration de la distribution d’une variable quantitative, il est souvent nécessaire de discrétiser la série statistique en plusieurs classes d’amplitude égale, car (en général) aucune valeur n’est identique.

Pour construire l’histogramme d’une distribution discrétisée en plusieurs classes d’amplitude égale, utilisez la fonction hist().

Dans l’exemple ci-dessous, nous utilisons la variable quantitative hp du dataframe mtcars :

# Pour représenter la distribution d'une série statistique sans la discrétiser préalablement -> hist()
hist(mtcars$hp, breaks=12, probability = TRUE)

3.2.2 Les valeurs centrales

En plus de l’histogramme, des résumés numériques (valeurs centrales, paramètres de dispersion absolue et relative) peuvent être calculés pour les variables quantitatives.

A noter que le mode peut être également calculé pour les variables qualitatives ordinales et nominales, et la médiane peut être calculé pour les variables qualitatives ordinales.

3.2.2.1 Moyenne

mean(mtcars$hp)
[1] 146.6875

3.2.2.2 Médiane

median(mtcars$hp)
[1] 123

3.2.2.3 Mode

# Mode = Valeurs qui a la fréquence la plus élévée
result <-  as.data.frame(table(mtcars$hp))

# Trier les valeurs par leur fréquence -> order()
result[order(result$Freq, decreasing = TRUE),]
   Var1 Freq
11  110    3
15  175    3
16  180    3
4    66    2
13  123    2
14  150    2
20  245    2
1    52    1
2    62    1
3    65    1
5    91    1
6    93    1
7    95    1
8    97    1
9   105    1
10  109    1
12  113    1
17  205    1
18  215    1
19  230    1
21  264    1
22  335    1

3.2.3 Les paramètres de dispersions absolue

Les paramètres de dispersion absolue se calculent uniquement sur les variables quantitatives.

3.2.3.1 Minimum

min(mtcars$hp)
[1] 52

3.2.3.2 Maximum

max(mtcars$hp)
[1] 335

3.2.3.3 Amplitude (étendue)

max(mtcars$hp) - min(mtcars$hp)
[1] 283

3.2.3.4 Quartiles

quantile(mtcars$hp)
   0%   25%   50%   75%  100% 
 52.0  96.5 123.0 180.0 335.0 

3.2.3.5 Quartiles, Moyenne et NA’s

summary(mtcars$hp)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   52.0    96.5   123.0   146.7   180.0   335.0 

3.2.3.6 Intervalle inter-quartile (Q3 - Q1)

summary(mtcars$hp)[5] - summary(mtcars$hp)[2]
3rd Qu. 
   83.5 

3.2.3.7 Variance

var(mtcars$hp)
[1] 4700.867

3.2.3.8 Écart-type

sd(mtcars$hp) 
[1] 68.56287

3.2.3.9 Coefficient de variation (en %) -

# = Ecart-type/moyenne * 100
sd(mtcars$hp) / mean(mtcars$hp) *100
[1] 46.74077

3.3 Discrétiser une variable

Il est nécessaire de définir la forme d’une la distribution pour la discrétiser correctement.

Ci-dessous, quelques formes classiques de distribution statistique :

En fonction du profil d’une distribution, on utilise différentes méthodes de discrétisation :

Amplitude égale

Longueur de l’intervalle entre la valeur minimum et maximum.

Toutes les classes ont la même amplitude. -> A privilégier pour les distributions uniformes ou symétriques.

Discrétisation standardisée

Les classes sont déterminées selon une fraction d’écart-type par rapport à la moyenne. -> A privilégier pour les distributions symétriques.

Par seuil observé Les bornes sont créées par observation de la distribution, de manière manuelle. -> A privilégier pour les distributions dissymétriques et/ou bimodales.

Effectifs égaux (quantiles) Les bornes sont construites en réalisant des classes d’effectifs égaux. -> A privilégier pour les distributions dissymétriques et/ou bimodales.

Q6 Variante de la discrétisation selon les quantiles avec isolement des classes extrêmes de la série. -> A privilégier pour les distributions dissymétriques et/ou bimodales.

Fisher-Jenks Les classes construites maximisent la variance inter-classe et minimisent la variance intra-classe. -> A privilégier pour les distributions dissymétriques et/ou bimodales.

Progression géométrique Les classes sont découpées selon une progression géométrique. -> A privilégier pour les distributions dissymétriques.

Progression arithmétique Les classes sont établies selon une progression arithmétique. -> A privilégier pour les distributions dissymétriques.

Important !

**Le choix d’un méthode de discrétisation et du nombre de classes à un impact très important sur l’interprétation de sa représentation visuelle. Cette application (Jégou 2017) en est une belle démonstration.

Pour discrétiser une série statistique, vous pouvez utiliser la fonction * mf_get_breaks(), du package mapsf (Giraud 2021).

Vous pouvez choisir différentes méthodes de discrétisation avec l’argument ‘breaks’.

# Pour accéder à la documentation de la fonction :
?mf_get_breaks

Pour enregistrer l’appartenance des individus aux différentes classes en fonction de la discrétisation, procédez de la manière suivante :

# Calcul des borne de classe
ma_discretisation <- mf_get_breaks(mtcars$hp, breaks = "sd")

# Utiliser la fonction cut()
mtcars$hp_classe <- cut(mtcars$hp, 
                        breaks = ma_discretisation, 
                        include.lowest = TRUE, 
                        right = TRUE)

mtcars$hp_classe 
 [1] (78.1,112]  (78.1,112]  (78.1,112]  (78.1,112]  (147,181]   (78.1,112] 
 [7] (215,250]   [43.8,78.1] (78.1,112]  (112,147]   (112,147]   (147,181]  
[13] (147,181]   (147,181]   (181,215]   (181,215]   (215,250]   [43.8,78.1]
[19] [43.8,78.1] [43.8,78.1] (78.1,112]  (147,181]   (147,181]   (215,250]  
[25] (147,181]   [43.8,78.1] (78.1,112]  (112,147]   (250,284]   (147,181]  
[31] (318,352]   (78.1,112] 
9 Levels: [43.8,78.1] (78.1,112] (112,147] (147,181] (181,215] ... (318,352]
# Préciser des nom de classe avec l'argument labels
mtcars$hp_classe <- cut(mtcars$hp, 
                        breaks = ma_discretisation, 
                        labels =  c("A","B","C","D","E","F","G","H","I"), 
                        include.lowest = TRUE, 
                        right = TRUE)

mtcars$hp_classe 
 [1] B B B B D B F A B C C D D D E E F A A A B D D F D A B C G D I B
Levels: A B C D E F G H I
# Pour changer les noms de classe
levels(mtcars$hp_classe) <- c("Aa","Bb","Cc","Dd","Ee","Ff","Gg","Hh","Ii")
mtcars$hp_classe
 [1] Bb Bb Bb Bb Dd Bb Ff Aa Bb Cc Cc Dd Dd Dd Ee Ee Ff Aa Aa Aa Bb Dd Dd Ff Dd
[26] Aa Bb Cc Gg Dd Ii Bb
Levels: Aa Bb Cc Dd Ee Ff Gg Hh Ii
# Visualiser le nombre d'éléments par classe - table()
table(mtcars$hp_classe)

Aa Bb Cc Dd Ee Ff Gg Hh Ii 
 5  9  3  8  2  3  1  0  1 

3.3.1 Représentation graphique

3.3.1.1 L’histogramme

# Afficher l'histogramme de la distribution
hist(mtcars$hp, breaks = 15, col = "grey", main = "Distribution de la variable hp")

# Ajouter la moyenne
abline(v=mean(mtcars$hp, na.rm=TRUE), col = "red", lwd = 4 , lty = 2 )

# Ajouter les bornes des classes
abline(v=ma_discretisation,col="blue", lwd = 2, lty = 2)

# Ajouter une légende
legend("topright", c("moyenne", "borne de classe"), fill= c(col="red", col="blue"), cex=0.8)

# Affichage de chaque individu
rug(mtcars$hp)

3.3.1.2 La boite à moustaches (boxplot) :

# Boite à moustache
boxplot(mtcars$qsec,
        main = "Distribution variable quantitative continue 'qsec'",
        xlab = "qsec",
        col = "orange",
        border = "brown",
        horizontal = TRUE)

# ajouter la série statistique en bas du boxplot
rug(mtcars$qsec)

3.3.1.3 La carte

La carte permet d’explorer la répartition spatiale d’une distribution d’une variable géographique. Plusieurs packages permettent de faire des carte avec R, le package mapsf est spécialisé dans la production de cartes thématiques et statistiques.

![figures/carto.png]{width = 50%} Source : https://riatelab.github.io/mapsf/index.html

Un exemple d’utilisation…

  1. Préparation des données :
# Import de la couche géographique
library(sf)
mtq <- st_read("data/martinique.shp")
Reading layer `martinique' from data source 
  `C:\Users\elina\Documents\R\stats_avec_r\data\martinique.shp' 
  using driver `ESRI Shapefile'
Simple feature collection with 34 features and 3 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 690574.4 ymin: 1592426 xmax: 736126.5 ymax: 1645660
Projected CRS: WGS 84 / UTM zone 20N
# Import des données de recensement
mtq_data <- read.csv("data/INSEE_COM_972.csv", header=TRUE, sep=",", stringsAsFactors=FALSE)

# Jointure shapefile - data
mtq <-  merge(mtq , mtq_data , by.x="INSEE_COM" , by.y="CODGEO")

# Calcul d'une variable quantitative relative (Densité de population)
mtq$POPDENS <- 1e6 * mtq$P16_POP / st_area(mtq)

# Calcul discrétisation 
ma_discretisation <- mf_get_breaks(mtq$POPDENS, breaks = "quantile")
  1. cartographie :
library(mapsf)

# Choix d'un thème graphique
mf_theme("iceberg")

# Carte par aplat de couleur
mf_map(x = mtq, 
       var = "POPDENS",
       type = "choro",
       breaks = ma_discretisation,
       pal = "Greens",
       border = "white", 
       lwd = 0.5,
       leg_pos = "left", 
       leg_title = "Population Density\n(people per km2)") 

# Mikse en page
mf_layout(title = "Population Distribution in Martinique", 
          credits = paste0("Sources: Insee and IGN, 2018\n",
                           "mapsf ", 
                           packageVersion("mapsf")))

3.4 Exercice

  1. Créez un nouveau projet (ou réutilisez le projet créé durant l’exercice 1).

  2. Chargez de nouveau le fichier INSEE_COM_972.csv, stocké dans le sous-répertoire ‘data’ de votre projet.

  3. Sélectionnez uniquement ces variables et créez un nouveau dataframe :

    • Code insee de la commune (CODGEO)
    • Nom de la commune (LIBGEO)
    • Libellé aire urbaine (LIBAU2010)
    • Catégorie commune dans aire urbaine (CATAEU2010)
    • Population total en 2016 (P16_POP)
    • Nombre de personnes de 15 ans et plus en 2016 (C16_POP15P)
    • Nombre d’agriculteurs et exploitants de 15 ans et plus (C16_POP15P_CS1)
    • Nombre de retraités de 15 ans et plus (C16_POP15P_CS7)
  4. Créez une nouvelle variable : la part de la population d’agriculteurs et exploitants dans la population active, et nommez cette nouvelle variable TX_CS1_2016

    • Quel est le taux minimum ?
    • Quel est le taux maximum ?
    • Quel est l’amplitude de la variable ?
    • Quelle est la moyenne ?
    • Quel indicateur divise la série statistique en deux ? Quelle est sa valeur ?
    • Quel est son écart-type, son intervalle interquartile ?
    • Représentez graphiquement la distribution ? (plusieurs solutions sont possibles)
  5. Discrétisez la variable TX_CS1_2016. Quelle méthode choisissez-vous ? Pourquoi ?

  6. Créez une variable qualitative à partir des valeurs de la variable *TX_CS1_2016. Plusieurs solutions sont possible, exemple :

  • Utiliser la fonction cut()
  • Utiliser un opérateur relationnel… (si TX_CS1_2016 < …, alors CAT_CS1_2016 == “FAIBLE”…)
  1. Réaliser une jointure entre la couche géographique de la Martinique et le tableau de données INSEE.

  2. Cartographiez la part d’agriculteurs et exploitant dans la population active.

4 Statistique bivariée

4.1 Vocabulaire

Statistique bivariée

C’est l’étude des relations entre deux variables, quantitatives et/ou qualitatives. Les analyses bivariées consistent ainsi à étudier des variables prises en couple, via des techniques descriptives ou probabilistes. L’objectif est de mettre en évidence un lien ou une absence de lien entre 2 variables, et d’étudier ce lien (sens, intensité) lorsqu’il existe.

L’analyse d’une relation bivariée avec deux types de variables possibles se résume à trois cas :
1- Relation entre deux variables qualitatives (3.2)
2- Relation entre une variable qualitative et une variable quantitative (3.3)
3- Relation entre deux variables quantitatives (3.4)

Test statistique

Un test statistique est une procédure de décision entre deux hypothèses. Il s’agit d’une démarche consistant à rejeter ou à ne pas rejeter une hypothèse statistique, appelée hypothèse nulle, en fonction d’un jeu de données (échantillon).

Corrélation

Mesure du lien d’association entre des phénomènes (variables) décrits par des séries statistiques. Le calcul d’une corrélation entre deux variables permet de savoir si elles sont liées. Attention, deux variables peuvent être fortement liées sans que l’une n’explique l’autre : https://www.tylervigen.com/spurious-correlations

Tableau de contingence (tableau croisé)

Pour déterminer s’il existe une relation entre deux variables étudiés, on construit un tableau de contingence.Les valeurs du tableau correspondent aux effectifs de population selon les modalités des deux variables. Ex :

Remarque

La construction d’un tableau de contingence est la première étape nécessaire pour évaluer la dépendance de deux variables qualitatives.

Résidu

Les résidus d’une régression expriment l’écart entre les valeurs observées et les valeurs prédites par le modèle. Plus un individu aura des résidus forts (positifs ou négatif), moins sa position sera expliquée par le modèle. Il faudra alors trouver d’autres facteurs explicatifs.

4.2 Deux variables qualitatives

Un couple de variables qualitatives se décrit par ses fréquences conjointes dans un tableau tris croisés . Les fréquences obtenues peuvent être calculées par rapport à l’effectif total ou par rapport aux effectifs marginaux (effectif en ligne et colonne). Il s’agit de l’une des analyses les plus fréquentes lors du traitement d’enquêtes en sciences sociales.

4.2.1 Tableaux croisés

La manière la plus simple d’obtenir un tableau croisé est d’utiliser la fonction table().

# Utilisation d'un jeu de donnéesdu package 'questionr'
head(hdv2003,3)
  id age  sexe                                              nivetud    poids
1  1  28 Femme Enseignement superieur y compris technique superieur 2634.398
2  2  23 Femme                                                 <NA> 9738.396
3  3  59 Homme                    Derniere annee d'etudes primaires 3994.102
                  occup     qualif freres.soeurs clso
1 Exerce une profession    Employe             8  Oui
2       Etudiant, eleve       <NA>             2  Oui
3 Exerce une profession Technicien             2  Non
                        relig                     trav.imp    trav.satisf
1 Ni croyance ni appartenance                Peu important Insatisfaction
2 Ni croyance ni appartenance                         <NA>           <NA>
3 Ni croyance ni appartenance Aussi important que le reste      Equilibre
  hard.rock lecture.bd peche.chasse cuisine bricol cinema sport heures.tv
1       Non        Non          Non     Oui    Non    Non   Non         0
2       Non        Non          Non     Non    Non    Oui   Oui         1
3       Non        Non          Non     Non    Non    Non   Oui         0
# tableau croisé avec table()
table(hdv2003$sport, hdv2003$qualif)
     
      Ouvrier specialise Ouvrier qualifie Technicien Profession intermediaire
  Non                166              215         44                       83
  Oui                 37               77         42                       77
     
      Cadre Employe Autre
  Non   117     401    38
  Oui   143     193    20
# Croiser trois variables ou plus
table(hdv2003$sport, hdv2003$cuisine, hdv2003$sexe)

Il est cependant difficile de comparer à partir des effectifs. Le package questionr fournit des fonctions permettant de calculer facilement les pourcentages lignes, colonnes et totaux d’un tableau croisé.

Les pourcentages en lignes ou en colonne s’obtiennent avec les fonctions rprop() et cprop(). Celles-ci s’appliquent au tableau croisé généré avec table() :

# Pourcentage en ligne d'un tableau croisé table(), avec lprop() du package 'questionr'
rprop(table(hdv2003$sport, hdv2003$cuisine))
          
           Non   Oui   Total
  Non       59.4  40.6 100.0
  Oui       49.8  50.2 100.0
  Ensemble  56.0  44.0 100.0
# Pourcentage en colonne d'un tableau croisé table(), avec cprop() du package 'questionr'
cprop(table(hdv2003$sport, hdv2003$cuisine))
       
        Non   Oui   Ensemble
  Non    67.8  58.8  63.8   
  Oui    32.2  41.2  36.1   
  Total 100.0 100.0 100.0   

Les pourcentages totaux s’obtiennent avec la fonction prop()

# Pourcentages totaux d'un tableau croisé
prop(table(hdv2003$sport, hdv2003$cuisine), 
     digit=2, 
     percent=TRUE)
       
        Non     Oui     Total  
  Non    37.95%  25.90%  63.85%
  Oui    18.00%  18.15%  36.15%
  Total  55.95%  44.05% 100.00%

4.2.2 Le khi-2 (χ²) et la mesure des écarts à l’indépendance

A partir d’un tableau croisée, on peut tester l’existence d’un lien entre les modalités de deux variables avec le test du χ².

Le test du χ² consiste à comparer la répartition observée à une répartition théorique sous hypothèse d’indépendance, c’est-à-dire la répartition que l’on observerait s’il n’y avait aucun lien entre les deux variables. Cette répartition théorique consiste donc à redistribuer les effectifs conjoints tout en conservant les effectifs marginaux.

Le test du χ² permet d’établir à quel seuil de probabilité on peut rejeter l’hypothèse d’indépendance entre des effectifs observés et des effectifs théoriques. Plus le χ² est proche de zéro, plus le tableau des effectifs théoriques et celui des effectifs observées se confondent.

Un test de χ² s’applique uniquement sur des tableaux de contingence :
- ayant au moins 2 lignes et 2 colonnes
- contenant des valeurs positives entières
- ayant au minimum 5 observations par cases du tableau et/ou dans le tableau des effectifs théoriques.

Lorsque toutes les cases du tableau n’ont pas plus de 5 observations par cases, il est conseillé d’effectuer des regroupement de modalités lorsque c’est possible.

La fonction chisq.test() permet de réaliser un test du du χ². Cette fonction renvoie une liste qui contient tous les éléments nécessaires à l’analyse du χ² : effectifs théoriques, résidus bruts ou résidus relatifs :

# 1) construction du tableau de contigence avec les effectifs réels
tab <- table(hdv2003$sport, hdv2003$qualif)

# 2) Test du Khi-2 sur le tableau de contingence
tab.chi2 <- chisq.test(tab)
tab.chi2

    Pearson's Chi-squared test

data:  tab
X-squared = 100.27, df = 6, p-value < 2.2e-16

La fonction chisq.test() renvoie automatiquement :

  • la statistique du χ2(X-squared)
  • le degré de liberté associé au test (df)
  • la significativité de la relation (p-value)
Interpréter les résultats ?

“La probabilité d’obtenir une valeur du χ² observée aussi élevée dans un échantillon de la taille observée sous l’hypothèse d’indépendance des deux variables est inférieure à 0.001%. Il est donc possible de rejeter l’hypothèse d’indépendance”.

Il semble bien exister une relation entre la CSP et la pratique du sport…

L’objet liste renvoyé contient également :

# Les effectifs observés
tab.chi2$observed
     
      Ouvrier specialise Ouvrier qualifie Technicien Profession intermediaire
  Non                166              215         44                       83
  Oui                 37               77         42                       77
     
      Cadre Employe Autre
  Non   117     401    38
  Oui   143     193    20
# Les effectifs théoriques
tab.chi2$expected
     
      Ouvrier specialise Ouvrier qualifie Technicien Profession intermediaire
  Non          130.66667          187.954   55.35632                102.98851
  Oui           72.33333          104.046   30.64368                 57.01149
     
          Cadre  Employe    Autre
  Non 167.35632 382.3448 37.33333
  Oui  92.64368 211.6552 20.66667

Pour correctement interpréter le résultat du test du χ², il est important de comprendre comment ces différentes valeurs sont calculées…

–> Le calcul du χ² et du degré de liberté ?
–> Le calcul de la valeur p (table de la loi du χ² ?)

Il est possible d’affiner l’interprétation du test en déterminant dans quelle “case” l’écart à l’indépendance est le plus significatif en utilisant les résidus du test. Ceux-ci sont notamment affichables avec la fonction chisq.residuals() de la librairie questionr :

# Résidus (de Pearson) du test khi-2 = (obs - exp) / sqrt(exp)

# tab.chi2$residuals fonctionne aussi !
chisq.residuals(tab)
     
      Ouvrier specialise Ouvrier qualifie Technicien Profession intermediaire
  Non               3.09             1.97      -1.53                    -1.97
  Oui              -4.15            -2.65       2.05                     2.65
     
      Cadre Employe Autre
  Non -3.89    0.95  0.11
  Oui  5.23   -1.28 -0.15

4.2.3 Représentations graphiques

4.2.3.1 Le tableau de contingence

tab <-  table(hdv2003$sport, hdv2003$qualif)

# Diagramme en bâton - Effectifs observés
barplot(tab, 
        main = "Pratique du sport selon le niveau de qualification\nEffectifs observés", 
        las=2)

legend("topright", 
       c("NON", "OUI"), 
       fill=c(col="grey40", col="grey90"), 
       cex=0.8)

# Diagramme en bâton - Fréquence des effectifs observés
barplot(cprop(tab, total = FALSE), 
        main = "Pratique du sport selon le niveau de qualification\nFréquences relatives des effectifs",
        las=2)

legend("topright",
       c("NON", "OUI"), 
       fill=c(col="grey40", col="grey90"), 
       cex=0.8)

4.2.3.2 Les résidus Pearson d’un test du χ²

La fonction mosaicplot() permet un représentation graphique du tableau de contingence des effectifs observés et des résidus de Pearson du test du χ² ((obs - exp) / sqrt(exp)).

la longueur des segments sur les deux axes correspond aux fréquences relatives correspondantes et l’aire des rectangles est également proportionnelle à la fréquence relative de la sous-population représentée. La couleur de la case correspond aux résidus Pearson du test du χ² :

# Fonction mosaicplot()
mosaicplot(qualif ~ sport, 
           data = hdv2003, 
           shade = TRUE, 
           main = "Résidus de Pearson du test du χ²", 
           cex=0.6)

les cases en rouge sont sous-représentées, les cases en bleu sur-représentées, et les cases blanches sont statistiquement proches de l’hypothèse d’indépendance.

4.3 Exercice

Dans le le tableau ci-dessous figurent en colonnes le nombre de réponses à la question “Faites-vous faire des recherches sur internet à vos élèves ?” posée à 179 enseignants de collèges en France :

  1. Construire le data.frame dans R.
  1. Convertissez les valeurs en fréquence relative (en ligne, colonne et total).

  2. Représenter graphiquement les fréquence relatives à l’aide de la fonction barplot().

  1. Réalisez un test du χ². Existe-t-il un lien statistique entre ces deux variables ?

  2. Représentez graphiquement les résidus de Pearson du test du χ² avec la fonction mosaicplot().

4.4 Qualitatif vs Quantitatif

Il existe plusieurs méthodes statistiques pour mesurer la dépendance entre une variable qualitative et une variable quantitative, comme le test t de student ou l’analyse de variance (ANOVA). Cependant, ces méthodes ne seront pas détaillé dans ce cours

Exemple de calcul du test t de student avec R (t.test()) :

# Nécessite une variable qualitative binaire (deux modalités max)
test.student <- t.test(age ~ sport, data = hdv2003)
test.student

    Welch Two Sample t-test

data:  age by sport
t = 15.503, df = 1600.4, p-value < 2.2e-16
alternative hypothesis: true difference in means between group Non and group Oui is not equal to 0
95 percent confidence interval:
  9.893117 12.759002
sample estimates:
mean in group Non mean in group Oui 
         52.25137          40.92531 

Exemple d’une analyse de variance avec R (aov()) :

# Nécessite une variable qualitative binaire (deux modalités max)
anova <- aov(age ~ sport, data=hdv2003)
anova
Call:
   aov(formula = age ~ sport, data = hdv2003)

Terms:
                   sport Residuals
Sum of Squares   59218.4  514544.3
Deg. of Freedom        1      1998

Residual standard error: 16.04773
Estimated effects may be unbalanced

4.4.1 Comparaison d’indicateurs

Comparer certains indicateurs (moyenne, médiane…) d’une variable quantitative selon les modalités d’une variable qualitative permet de mesurer des différence entre plusieurs sous-population.

Dans un premier temps, ventilez votre population en autant de sous-populations qu’il y a de modalités dans la variable qualitative. Pour cela, utilisez la fonction subset() :

# On crée deux tables de sous-population

# Sous-population pratiquant du sport :
hdv2003_sport <- subset(hdv2003, sport == "Oui")
# Sous-population non-pratiquante :
hdv2003_nonsport <- subset(hdv2003, sport == "Non")
# Moyenne d'age des pratiquants
mean(hdv2003_sport$age)
[1] 40.92531
# Moyenne d'age des non-pratiquants
mean(hdv2003_nonsport$age)
[1] 52.25137

Vous pouvez également utiliser la fonction tapply(), qui prend en paramètre une variable quantitative, qualitative et une fonction, puis applique automatiquement la fonction aux valeurs de la variables quantitative pour chaque niveau de la variable qualitative. Ex :

# Fonction tapply()
tapply(hdv2003$age, hdv2003$sport, mean)
     Non      Oui 
52.25137 40.92531 

4.4.2 Représentations graphiques

Il est possible de résumer visuellement la distribution statistique d’une variable quantitative autour de différentes mesures de centralité et de dispersion en utilisant la “boîte à moustache” (boxplot).

La fonction boxplot() représente la distribution de la variable quantitative pour chacune des modalités de la variable qualitative :

# Fonction mosaicplot()
boxplot(hdv2003$heures.tv ~ hdv2003$qualif, 
        col="firebrick3",
        ylab="heures TV",
        las=2)

Dans le cas où une variable qualitative ne présente que deux modalités, la représentation côte à côte des deux distributions permet d’observer facilement leurs différences :

# Construction du tableau croisé, en format data.frame
tab <- as.data.frame(lprop(table(hdv2003$sport, hdv2003$age)))
colnames(tab) <- c("sport", "age", "Freq")
tab <-  subset(tab , !(sport %in% "Ensemble"))

# Utilisation de la fonction ggplot()
library(ggplot2)
ggplot(tab , aes(x = age, y = Freq, fill = factor(sport))) +
  geom_bar(stat = "identity", position = position_dodge(), las=2) +
  ylab("Pourcentage") +
  scale_x_discrete(breaks=seq(17,97,3), labels = seq(17,97,3)) +
  scale_y_continuous(limit=c(0,3.3))

4.5 Deux variables quantitatives

4.5.1 Représentation graphique

Lorsque l’on croise deux variables quantitatives, l’idéal est de faire une représentation graphique sous forme de nuage de points. Cela permet de visualiser l’existence d’un lien entre les deux variables et de ne pas faire d’erreurs d’interprétation.

Figure : Différentes séries statistiques… aux paramètres identiques

Source : http://blog.revolutionanalytics.com/2017/05/the-datasaurus-dozen.html

Commencez par charger le jeu de données du recensement de la population de 2012 (rp2012) mis à disposition par le package questionr.

library(questionr)
data(rp2012)

Pour tracer un nuage de points, utilisez la fonction plot() :

plot(rp2012$cadres, rp2012$dipl_sup)

Il est possible de personnaliser le graphique…

par(bg = "ivory", mar = c(2,2,2,2), family="")
plot(x = rp2012$cadres, y = rp2012$dipl_sup, asp = 1, pch = 21, col = "white", 
     ylim = c(0,60), cex = 0.5, bg = "red", lwd = 0.5, axes = F)
axis(side = 1, at = seq(from = 0,to = 60, by = 10), cex.axis = 0.8,
     pos = 0, tck=-0.01, padj = -1)
axis(side = 2, at = seq(from = 0,to = 60, by = 10), cex.axis = 0.8,
     labels = c("", seq(from = 10,to = 60, by = 10) ), pos = 0, tck=-0.01, las = 2)
mtext(text = "Relation entre niveau d'étude et CSP", side = 3, line = 0.75,
      adj = 0,font = 4)
mtext(text = "Diplômés du supérieur (%)", side = 2, line = 1)
mtext(text = "Cadres (%)", side = 1, line = 1)

4.5.2 Interpréter un nuage de points

Quelques formes classiques de relation entre 2 variables :

![figures/correlation.png]

Source : https://eric.univ-lyon2.fr/~ricco/cours/cours/Analyse_de_Correlation.pdf

4.5.3 Calcul d’indicateurs

En plus d’une représentation graphique, on peut calculer certains indicateurs permettant de mesurer le degré d’association de deux variables quantitatives.

4.5.3.1 Corrélation linéaire (Pearson)

La corrélation est une mesure du lien d’association linéaire entre deux variables quantitatives. Sa valeur varie entre -1 et 1. Si la corrélation vaut -1, il s’agit d’une association linéaire négative parfaite. Si elle vaut 1, il s’agit d’une association linéaire positive parfaite. Si elle vaut 0, il n’y a aucune association linéaire entre les variables.

Le calcul du coefficient linéaire peut se faire avec la fonction cor.test() :

# Fonction primitive cor.test()
cor.test(rp2012$cadres, rp2012$dipl_sup) 

    Pearson's product-moment correlation

data:  rp2012$cadres and rp2012$dipl_sup
t = 193.1, df = 5168, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 0.9337577 0.9403985
sample estimates:
      cor 
0.9371629 

Dans ce cas, le coefficient est extrêmement fort. Il y a donc un lien linéaire et positif entre les deux variables (quand la valeur de l’une augmente, la valeur de l’autre augmente également).

4.5.3.2 Corrélation des rangs (Spearman)

Si les deux variables ne semblent pas être corrélées de façon linéaire et que l’on est en présence d’une relation monotone (c’est à dire que les variables ont tendance à se déplacer dans la même direction relative), on peut utiliser le coefficient de corrélation des rangs de Spearman.

Plutôt que de se baser sur les valeurs des variables, cette corrélation va se baser sur leurs rangs, c’est-à-dire sur leur position parmi les différentes valeurs prises par les variables.

Ainsi, si la valeur la plus basse de la première variable est associée à la valeur la plus basse de la deuxième, et ainsi de suite jusqu’à la valeur la plus haute, on obtiendra une corrélation de 1. Si la valeur la plus forte de la première variable est associée à la valeur la plus faible de la seconde, et ainsi de suite, et que la valeur la plus faible de la première est associée à la plus forte de la deuxième, on obtiendra une corrélation de -1. Si les rangs sont “mélangés”, sans rapports entre eux, on obtiendra une corrélation autour de 0.

Pour calculer une corrélation de Spearman, utilisez la fonction cor() (argument method = “spearman”) :

# Calcul coefficient de Corrélation de Spearman
cor(rp2012$cadres, rp2012$dipl_sup, method = "spearman")
[1] 0.9036273

4.5.4 Régression linéaire

Dans le cas particulier où l’on a pu mettre en évidence l’existence d’une relation linéaire significative entre deux caractères quantitatifs continus X et Y, on peut chercher à formaliser la relation moyenne qui unit ces deux variables à l’aide des équations suivantes :

Y = aX + b = droite de régression de Y en fonction de X
X = aY + b = droite de régression de X en fonction de Y

La régression consiste à évaluer les paramètres d’une fonction linéaire, puis d’estimer à l’aide de cette fonction les valeurs de la variable à expliquer et à tester si les différences (= les résidus) entre valeurs mesurées et valeurs estimées s’écartent de manière significative de 0.

# Regression linéaire - fonction lm()
lm(rp2012$cadres ~ rp2012$dipl_sup)

Call:
lm(formula = rp2012$cadres ~ rp2012$dipl_sup)

Coefficients:
    (Intercept)  rp2012$dipl_sup  
         0.9217           1.0816  

lm() nous renvoie les coefficients de la droite de régression, où :

Y = % de cadres
X = % diplomé du supérieur

b = ordonnée à l’origine (Intercept) vaut 0.92 a = le coefficient associé à dipl_sup vaut 1.08

La régression linéaire de Y en fonction de X ( Y = aX + b ) équivaut donc à Y = 1.08X + 0.92

4.5.4.1 Coefficient de détermination (R2)

Le coefficient de détermination (R2) est une mesure de la qualité de la prédiction d’une régression linéaire. Il donne la part de la variance expliquée par l’équation de la régression dans la variance totale du nuage de points.

Pour calculer le R2, combinez les fonctions summary() et lm() :

# Pour des résultats plus détaillés, fonction summary :
summary(lm(rp2012$cadres ~ rp2012$dipl_sup))

Call:
lm(formula = rp2012$cadres ~ rp2012$dipl_sup)

Residuals:
    Min      1Q  Median      3Q     Max 
-33.218  -1.606  -0.172   1.491  13.001 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)     0.921661   0.071814   12.83   <2e-16 ***
rp2012$dipl_sup 1.081636   0.005601  193.10   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.701 on 5168 degrees of freedom
Multiple R-squared:  0.8783,    Adjusted R-squared:  0.8783 
F-statistic: 3.729e+04 on 1 and 5168 DF,  p-value: < 2.2e-16

4.5.4.2 Représentation graphique

On peut enfin représenter la droite de régression sur notre nuage de points à l’aide de la fonction abline() :

plot(rp2012$dipl_sup, rp2012$cadres)
abline(lm(rp2012$cadres ~ rp2012$dipl_sup), col="red", lwd=2)
text(6, 55, "y = 1.08x + 0.92", col="red")

4.5.5 Les résidus

Les résidus d’une régression expriment l’écart entre les valeurs observées et les valeurs prédites par le modèle. Plus un individu aura des résidus forts (positifs ou négatif), moins sa position sera expliquée par le modèle. Il faudra alors trouver d’autres facteurs explicatifs.

Calculer les résidus :

# Regression lineaire
my_reg <- lm(rp2012$cadres ~ rp2012$dipl_sup)

# Construction d'un data.frame des résidus normalisés
residus <- data.frame(scaledRes = scale(my_reg$residuals), nom = row.names(rp2012))

Représenter les résidus :

# on ne garde que le nom des individus ayant des résidus trés élevés (sup à 4 ecarts-type)
residus[residus$scaledRes < 4 & residus$scaledRes > -4, "nom"] <- NA

# affichage des résidus
plot(residus$scaledRes, cex = .5, pch = 20, ylim=c(-5,5))
# intervalles exprimés en ecart-type
abline(h = 0, lwd = 2, col = "red")     
abline(h = 4, lty = 2)
abline(h = -4, lty = 2)
# affichage du nom des individus extraordinaires
text(x= 1:nrow(residus), y = residus$scaledRes, labels = residus$nom, pos = 4, 
     cex = 0.7, offset = c(.2,0), font = 2)

4.6 Exercice

Pour cet exercice, utilisez le jeu de données women (R-base).

?women
data(women)
head(women)
  1. Créez un nouveau projet.

  2. Décrivez le jeu de données “women”. Quelles sont les unités de mesure des variables ?

  3. Créer deux nouvelles variables (taille et poids) dans des unités de mesures plus compréhensibles. Arrondissez les valeurs pour une meilleure lisibilité (avec quelles fonctions ?).

  4. Créez un graphique mettant en relation les deux variables (poids et taille).

  5. Quelle hypothèse pouvons-nous faire ? Et comment la vérifier ?

  6. Quelle est la relation entre poids et taille ?

  7. Comment modéliser cette relation ?

  8. Quel serait le poids d’une femme d’1.68 m ?

  9. Afficher la droite de régression du modèle sur le graphique.

5 Sources & références

5.1 Langage R

Il existe de très nombreuses ressources documentaires sur R, disponible en libre accès sur le web. De nombreuses ressources de qualité, parfois largement utilisées pour produire ce document, sont référencées sur le site de partage et de diffusion rzine.fr (onglet ressources).

[!figures/Rzine_logo.png]

5.2 Statistique en géographie (et R)

Barnier, julien. 2016. “Tout Ce Que Vous n’avez Jamais Voulu Savoir Sur Le Khi2 Sans Jamais Avoir Eu Envie de Le Demander.” https://raw.githubusercontent.com/juba/archive_doc_khi2/master/khi2.pdf.
Béguin, Michèle, and Denise Pumain. 2000. La Représentation Des Données Géographiques : Statistique Et Cartographie. 2e éd. Cursus Géographie. Paris: Armand Colin.
Campion, Grégoire Le. 2020. “Analyse Des Corrélations Avec Easystats.” Rzine. https://rzine.fr/docs/20200526_glecampion_initiation_aux_correlations/rapp_correlation.html.
Giraud, Timothée. 2021. Mapsf: Thematic Cartography. https://CRAN.R-project.org/package=mapsf.
Jégou, Laurent. 2017. “Géovisualisation Des Discrétisations - Une Petite Application Pédagogique.” M@ppemonde 119. http://mappemonde.mgm.fr/119geov1.
Makowski, Dominique, Mattan S. Ben-Shachar, and Daniel Lüdecke. 2020. “The Easystats Collection of r Packages.” GitHub. https://github.com/easystats/easystats.
Poinsot, Denis. 2005. R Pour Les Statophobes. https://perso.univ-rennes1.fr/denis.poinsot/Statistiques_%20pour_statophobes/R%20pour%20les%20statophobes.pdf.

Info session